Skip to content

Commit

Permalink
Merge #2798 #2807 #2816
Browse files Browse the repository at this point in the history
2798: Remove unused Arbitrary instance r=jonathanknowles a=sevanspowell

## Overview

- Removed an Arbitrary instance that isn't used.


2807: Identify UTxOs suitable for use as collateral r=jonathanknowles a=sevanspowell

# Issue Number

ADP-1053


# Overview

- Added a function `asCollateral` to identify UTxOs suitable as collateral inputs.
- Clarified the meaning of a "VK input".
- Thoroughly tested the collateral functions.
- Added a property test to test the behaviour of `TokenBundle.toCoin`.

# Comments
[
I've clarified with the ledger team](https://input-output-rnd.slack.com/archives/CCRB7BU8Y/p1628060541075300) that a UTxO is to be considered suitable for collateral iff the payment credential associated with the output address of the UTxO is of type "key hash".

See the "Binary Address Format" heading of this spec: https://hydra.iohk.io/build/6752483/download/1/ledger-spec.pdf


2816: Bump version to v2021-08-11 r=Anviking a=Anviking

- [x] Bump wallet version to v2021-08-10 in preparation for release

### Issue Number

Release.

### Comments

Dependent on #2811 

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


Co-authored-by: Samuel Evans-Powell <[email protected]>
Co-authored-by: Jonathan Knowles <[email protected]>
Co-authored-by: Johannes Lund <[email protected]>
  • Loading branch information
4 people authored Aug 10, 2021
4 parents 23b9331 + aa9633f + 878284b + d4a6eb0 commit 9cc1b56
Show file tree
Hide file tree
Showing 21 changed files with 1,035 additions and 27 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ See **Installation Instructions** for each available [release](https://github.co
> | cardano-wallet | cardano-node (compatible versions) | SMASH (compatible versions)
> | --- | --- | ---
> | `master` branch | [alonzo-purple-1.0.1](https://github.com/input-output-hk/cardano-node/releases/tag/alonzo-purple-1.0.1) | [1.4.0](https://github.com/input-output-hk/smash/releases/tag/1.4.0)
> | [v2021-08-11](https://github.com/input-output-hk/cardano-wallet/releases/tag/v2021-08-11) | [alonzo-purple-1.0.1](https://github.com/input-output-hk/cardano-node/releases/tag/alonzo-purple-1.0.1) | [1.4.0](https://github.com/input-output-hk/smash/releases/tag/1.4.0)
> | [v2021-07-30](https://github.com/input-output-hk/cardano-wallet/releases/tag/v2021-07-30) | [1.28.0](https://github.com/input-output-hk/cardano-node/releases/tag/1.28.0) | [1.4.0](https://github.com/input-output-hk/smash/releases/tag/1.4.0)
> | [v2021-06-11](https://github.com/input-output-hk/cardano-wallet/releases/tag/v2021-06-11) | [1.27.0](https://github.com/input-output-hk/cardano-node/releases/tag/1.27.0) | [1.4.0](https://github.com/input-output-hk/smash/releases/tag/1.4.0)
> | [v2021-05-26](https://github.com/input-output-hk/cardano-wallet/releases/tag/v2021-05-26) | [1.26.2](https://github.com/input-output-hk/cardano-node/releases/tag/1.26.2) | [1.4.0](https://github.com/input-output-hk/smash/releases/tag/1.4.0)
## How to build from sources

Expand Down
4 changes: 2 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version: "3.5"

services:
cardano-node:
image: inputoutput/cardano-node:1.28.0
image: inputoutput/cardano-node:alonzo-purple-1.0.1
environment:
NETWORK:
volumes:
Expand All @@ -18,7 +18,7 @@ services:
max-size: "50m"

cardano-wallet:
image: inputoutput/cardano-wallet:2021.7.30
image: inputoutput/cardano-wallet:2021.8.11
volumes:
- wallet-${NETWORK}-db:/wallet-db
- node-ipc:/ipc
Expand Down
2 changes: 1 addition & 1 deletion lib/cli/cardano-wallet-cli.cabal
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: cardano-wallet-cli
version: 2021.7.30
version: 2021.8.11
synopsis: Utilities for a building Command-Line Interfaces
homepage: https://github.com/input-output-hk/cardano-wallet
author: IOHK Engineering Team
Expand Down
2 changes: 1 addition & 1 deletion lib/core-integration/cardano-wallet-core-integration.cabal
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: cardano-wallet-core-integration
version: 2021.7.30
version: 2021.8.11
synopsis: Core integration test library.
description: Shared core functionality for our integration test suites.
homepage: https://github.com/input-output-hk/cardano-wallet
Expand Down
13 changes: 12 additions & 1 deletion lib/core/cardano-wallet-core.cabal
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: cardano-wallet-core
version: 2021.7.30
version: 2021.8.11
synopsis: The Wallet Backend for a Cardano node.
description: Please see README.md
homepage: https://github.com/input-output-hk/cardano-wallet
Expand Down Expand Up @@ -41,6 +41,7 @@ library
, cardano-api
, cardano-crypto
, cardano-numeric
, cardano-ledger-core
, cardano-slotting
, cborg
, containers
Expand Down Expand Up @@ -183,6 +184,7 @@ library
Cardano.Wallet.Primitive.SyncProgress
Cardano.Wallet.Primitive.CoinSelection.Collateral
Cardano.Wallet.Primitive.CoinSelection.MA.RoundRobin
Cardano.Wallet.Primitive.Collateral
Cardano.Wallet.Primitive.Delegation.UTxO
Cardano.Wallet.Primitive.Migration
Cardano.Wallet.Primitive.Migration.Planning
Expand Down Expand Up @@ -255,11 +257,17 @@ test-suite unit
base
, aeson
, aeson-qq
, base58-bytestring
, binary
, bytestring
, cardano-addresses
, cardano-api
, cardano-binary
, cardano-crypto
, cardano-numeric
, cardano-ledger-byron
, cardano-ledger-byron-test
, cardano-ledger-core
, cardano-wallet-core
, cardano-wallet-launcher
, cardano-wallet-test-utils
Expand All @@ -280,6 +288,7 @@ test-suite unit
, foldl
, generic-arbitrary
, generic-lens
, hedgehog-quickcheck
, hspec >= 2.8.2
, hspec-core >= 2.8.2
, http-api-data
Expand Down Expand Up @@ -311,6 +320,7 @@ test-suite unit
, scrypt
, servant
, servant-server
, shelley-spec-ledger-test
, should-not-typecheck
, splitmix
, strict-non-empty-containers
Expand Down Expand Up @@ -374,6 +384,7 @@ test-suite unit
Cardano.Wallet.Primitive.AddressDiscoverySpec
Cardano.Wallet.Primitive.CoinSelection.CollateralSpec
Cardano.Wallet.Primitive.CoinSelection.MA.RoundRobinSpec
Cardano.Wallet.Primitive.CollateralSpec
Cardano.Wallet.Primitive.MigrationSpec
Cardano.Wallet.Primitive.Migration.PlanningSpec
Cardano.Wallet.Primitive.Migration.SelectionSpec
Expand Down
197 changes: 197 additions & 0 deletions lib/core/src/Cardano/Wallet/Primitive/Collateral.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
{-# LANGUAGE BinaryLiterals #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

-- |
-- For a UTxO to be considered a suitable collateral input, it must:
-- - Be a pure ADA UTxO (no tokens)
-- - Require a verification key witness to be spent
-- - Not be locked by a script
--
-- UTxOs of this kind are sometimes referred to as "VK" inputs.

module Cardano.Wallet.Primitive.Collateral
(
-- * Data types
AddressType(..)
, Credential(..)

-- * Classifying address types
, asCollateral
, addressSuitableForCollateral
, addressTypeSuitableForCollateral

-- * Reading address types
, addressTypeFromHeaderNibble
, getAddressType
, addressType

-- * Writing address types
, addressTypeToHeaderNibble
, putAddressType
) where

import Prelude

import Cardano.Wallet.Primitive.Types.Address
( Address (..) )
import Cardano.Wallet.Primitive.Types.Coin
( Coin )
import Cardano.Wallet.Primitive.Types.Tx
( TxOut (..) )
import Data.Word
( Word8 )
import Data.Word.Odd
( Word4 )

import qualified Cardano.Wallet.Primitive.Types.TokenBundle as TokenBundle
import qualified Data.Binary.Get as B
import qualified Data.Binary.Put as B
import qualified Data.Bits as Bits
import qualified Data.ByteString.Lazy as BL

-- In the realm of cardano-ledger-specs, we recognize the following types of
-- addresses:
-- (see https://hydra.iohk.io/build/6752483/download/1/ledger-spec.pdf):
--
-- | Address type | Payment Credential | Stake Credential | Header, first nibble |
-- |--------------------+--------------------+------------------+----------------------|
-- | Base address | keyhash | keyhash | 0000 |
-- | | scripthash | keyhash | 0001 |
-- | | keyhash | scripthash | 0010 |
-- | | scripthash | scripthash | 0011 |
-- | Pointer address | keyhash | ptr | 0100 |
-- | | scripthash | ptr | 0101 |
-- | Enterprise address | keyhash | - | 0110 |
-- | | scripthash | 0 | 0111 |
-- | Bootstrap address | keyhash | - | 1000 |
-- | Stake address | - | keyhash | 1110 |
-- | | - | scripthash | 1111 |
-- | Future formats | ? | ? | 1001-1101 |
--
-- We represent these types of addresses with the following data types:

-- | The type of the address.
data AddressType
= BaseAddress Credential Credential
| PointerAddress Credential
| EnterpriseAddress Credential
| StakeAddress Credential
| BootstrapAddress
-- ^ A Bootstrap (a.k.a. Byron) address
deriving (Eq, Show)

-- | The type of the credential used in an address.
data Credential
= CredentialKeyHash
| CredentialScriptHash
deriving (Eq, Show)

-- To parse the address type, we can inspect the first four bits (nibble) of the
-- address:

-- | Construct an @AddressType@ from the binary representation.
addressTypeFromHeaderNibble :: Word4 -> Maybe AddressType
addressTypeFromHeaderNibble = \case
0b0000 -> Just (BaseAddress CredentialKeyHash CredentialKeyHash)
0b0001 -> Just (BaseAddress CredentialScriptHash CredentialKeyHash)
0b0010 -> Just (BaseAddress CredentialKeyHash CredentialScriptHash)
0b0011 -> Just (BaseAddress CredentialScriptHash CredentialScriptHash)
0b0100 -> Just (PointerAddress CredentialKeyHash)
0b0101 -> Just (PointerAddress CredentialScriptHash)
0b0110 -> Just (EnterpriseAddress CredentialKeyHash)
0b0111 -> Just (EnterpriseAddress CredentialScriptHash)
0b1000 -> Just (BootstrapAddress)
0b1110 -> Just (StakeAddress CredentialKeyHash)
0b1111 -> Just (StakeAddress CredentialScriptHash)
_ -> Nothing

-- | Get an AddressType from a binary stream.
getAddressType :: B.Get AddressType
getAddressType = do
headerAndNetwork <- B.getWord8
let headerNibble =
fromIntegral @Word8 @Word4 (headerAndNetwork `Bits.shiftR` 4)
maybe
(fail "Unknown address type.")
(pure)
(addressTypeFromHeaderNibble headerNibble)

-- For testing and other purposes, it is also helpful to have a way of writing
-- the AddressType back to a binary stream.

-- | Return the binary representation of an @AddressType@.
addressTypeToHeaderNibble :: AddressType -> Word4
addressTypeToHeaderNibble = \case
BaseAddress CredentialKeyHash CredentialKeyHash -> 0b0000
BaseAddress CredentialScriptHash CredentialKeyHash -> 0b0001
BaseAddress CredentialKeyHash CredentialScriptHash -> 0b0010
BaseAddress CredentialScriptHash CredentialScriptHash -> 0b0011
PointerAddress CredentialKeyHash -> 0b0100
PointerAddress CredentialScriptHash -> 0b0101
EnterpriseAddress CredentialKeyHash -> 0b0110
EnterpriseAddress CredentialScriptHash -> 0b0111
BootstrapAddress -> 0b1000
StakeAddress CredentialKeyHash -> 0b1110
StakeAddress CredentialScriptHash -> 0b1111

-- | Write an AddressType to a binary stream.
putAddressType :: AddressType -> B.Put
putAddressType t =
B.putWord8 $
fromIntegral @Word4 @Word8 (addressTypeToHeaderNibble t) `Bits.shiftL` 4

-- | Indicates whether or not the given address is suitable for collateral.
--
addressSuitableForCollateral :: Address -> Bool
addressSuitableForCollateral =
maybe False addressTypeSuitableForCollateral . addressType

-- By inspecting the bit pattern of an Address, we can determine its address
-- type.

-- | Get the address type of a given address.
addressType :: Address -> Maybe AddressType
addressType (Address bytes) =
case B.runGetOrFail getAddressType (BL.fromStrict bytes) of
Left _ ->
Nothing
Right (_, _, addrType) ->
Just addrType

-- The funds associated with an address are considered suitable for use as
-- collateral iff the payment credential column of that address is "key hash".

-- | A simple function which determines if an @AddressType@ is suitable for use
-- as collateral. Only @AddressType@s with a "key hash" payment credential are
-- considered suitable for use as collateral.
addressTypeSuitableForCollateral :: AddressType -> Bool
addressTypeSuitableForCollateral = \case
BaseAddress CredentialKeyHash CredentialKeyHash -> True
BaseAddress CredentialKeyHash CredentialScriptHash -> True
BaseAddress CredentialScriptHash CredentialKeyHash -> False
BaseAddress CredentialScriptHash CredentialScriptHash -> False
PointerAddress CredentialKeyHash -> True
PointerAddress CredentialScriptHash -> False
EnterpriseAddress CredentialKeyHash -> True
EnterpriseAddress CredentialScriptHash -> False
StakeAddress CredentialKeyHash -> False
StakeAddress CredentialScriptHash -> False
BootstrapAddress -> True

-- | If the given @TxOut@ represents a UTxO that is suitable for use as
-- a collateral input, returns @Just@ along with the total ADA value of the
-- UTxO. Otherwise returns @Nothing@ if it is not a suitable collateral value.
asCollateral
:: TxOut
-- ^ TxOut from a UTxO entry
-> Maybe Coin
-- ^ The total ADA value of that UTxO if it is suitable for collateral,
-- otherwise Nothing.
asCollateral txOut
| addressSuitableForCollateral (address txOut) =
TokenBundle.toCoin (tokens txOut)
| otherwise =
Nothing
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,6 @@ import Test.QuickCheck
, Property
, applyFun
, arbitraryBoundedEnum
, arbitrarySizedNatural
, checkCoverage
, choose
, conjoin
Expand All @@ -178,7 +177,6 @@ import Test.QuickCheck
, label
, oneof
, property
, shrinkIntegral
, shrinkList
, sublistOf
, suchThat
Expand Down Expand Up @@ -3480,10 +3478,6 @@ instance Arbitrary AssetId where
arbitrary = genAssetId
shrink = shrinkAssetId

instance Arbitrary Natural where
arbitrary = arbitrarySizedNatural
shrink = shrinkIntegral

instance Arbitrary MakeChangeData where
arbitrary = genMakeChangeData

Expand Down
Loading

0 comments on commit 9cc1b56

Please sign in to comment.