Skip to content

Commit 9cc1b56

Browse files
iohk-bors[bot]sevanspowelljonathanknowlesAnviking
authored
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]>
4 parents 23b9331 + aa9633f + 878284b + d4a6eb0 commit 9cc1b56

21 files changed

+1035
-27
lines changed

Diff for: README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ See **Installation Instructions** for each available [release](https://github.co
6969
> | cardano-wallet | cardano-node (compatible versions) | SMASH (compatible versions)
7070
> | --- | --- | ---
7171
> | `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)
72+
> | [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)
7273
> | [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)
7374
> | [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)
74-
> | [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)
7575
7676
## How to build from sources
7777

Diff for: docker-compose.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ version: "3.5"
22

33
services:
44
cardano-node:
5-
image: inputoutput/cardano-node:1.28.0
5+
image: inputoutput/cardano-node:alonzo-purple-1.0.1
66
environment:
77
NETWORK:
88
volumes:
@@ -18,7 +18,7 @@ services:
1818
max-size: "50m"
1919

2020
cardano-wallet:
21-
image: inputoutput/cardano-wallet:2021.7.30
21+
image: inputoutput/cardano-wallet:2021.8.11
2222
volumes:
2323
- wallet-${NETWORK}-db:/wallet-db
2424
- node-ipc:/ipc

Diff for: lib/cli/cardano-wallet-cli.cabal

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: cardano-wallet-cli
2-
version: 2021.7.30
2+
version: 2021.8.11
33
synopsis: Utilities for a building Command-Line Interfaces
44
homepage: https://github.com/input-output-hk/cardano-wallet
55
author: IOHK Engineering Team

Diff for: lib/core-integration/cardano-wallet-core-integration.cabal

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: cardano-wallet-core-integration
2-
version: 2021.7.30
2+
version: 2021.8.11
33
synopsis: Core integration test library.
44
description: Shared core functionality for our integration test suites.
55
homepage: https://github.com/input-output-hk/cardano-wallet

Diff for: lib/core/cardano-wallet-core.cabal

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: cardano-wallet-core
2-
version: 2021.7.30
2+
version: 2021.8.11
33
synopsis: The Wallet Backend for a Cardano node.
44
description: Please see README.md
55
homepage: https://github.com/input-output-hk/cardano-wallet
@@ -41,6 +41,7 @@ library
4141
, cardano-api
4242
, cardano-crypto
4343
, cardano-numeric
44+
, cardano-ledger-core
4445
, cardano-slotting
4546
, cborg
4647
, containers
@@ -183,6 +184,7 @@ library
183184
Cardano.Wallet.Primitive.SyncProgress
184185
Cardano.Wallet.Primitive.CoinSelection.Collateral
185186
Cardano.Wallet.Primitive.CoinSelection.MA.RoundRobin
187+
Cardano.Wallet.Primitive.Collateral
186188
Cardano.Wallet.Primitive.Delegation.UTxO
187189
Cardano.Wallet.Primitive.Migration
188190
Cardano.Wallet.Primitive.Migration.Planning
@@ -255,11 +257,17 @@ test-suite unit
255257
base
256258
, aeson
257259
, aeson-qq
260+
, base58-bytestring
261+
, binary
258262
, bytestring
259263
, cardano-addresses
260264
, cardano-api
265+
, cardano-binary
261266
, cardano-crypto
262267
, cardano-numeric
268+
, cardano-ledger-byron
269+
, cardano-ledger-byron-test
270+
, cardano-ledger-core
263271
, cardano-wallet-core
264272
, cardano-wallet-launcher
265273
, cardano-wallet-test-utils
@@ -280,6 +288,7 @@ test-suite unit
280288
, foldl
281289
, generic-arbitrary
282290
, generic-lens
291+
, hedgehog-quickcheck
283292
, hspec >= 2.8.2
284293
, hspec-core >= 2.8.2
285294
, http-api-data
@@ -311,6 +320,7 @@ test-suite unit
311320
, scrypt
312321
, servant
313322
, servant-server
323+
, shelley-spec-ledger-test
314324
, should-not-typecheck
315325
, splitmix
316326
, strict-non-empty-containers
@@ -374,6 +384,7 @@ test-suite unit
374384
Cardano.Wallet.Primitive.AddressDiscoverySpec
375385
Cardano.Wallet.Primitive.CoinSelection.CollateralSpec
376386
Cardano.Wallet.Primitive.CoinSelection.MA.RoundRobinSpec
387+
Cardano.Wallet.Primitive.CollateralSpec
377388
Cardano.Wallet.Primitive.MigrationSpec
378389
Cardano.Wallet.Primitive.Migration.PlanningSpec
379390
Cardano.Wallet.Primitive.Migration.SelectionSpec

Diff for: lib/core/src/Cardano/Wallet/Primitive/Collateral.hs

+197
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
{-# LANGUAGE BinaryLiterals #-}
2+
{-# LANGUAGE DataKinds #-}
3+
{-# LANGUAGE LambdaCase #-}
4+
{-# LANGUAGE ScopedTypeVariables #-}
5+
{-# LANGUAGE TypeApplications #-}
6+
7+
-- |
8+
-- For a UTxO to be considered a suitable collateral input, it must:
9+
-- - Be a pure ADA UTxO (no tokens)
10+
-- - Require a verification key witness to be spent
11+
-- - Not be locked by a script
12+
--
13+
-- UTxOs of this kind are sometimes referred to as "VK" inputs.
14+
15+
module Cardano.Wallet.Primitive.Collateral
16+
(
17+
-- * Data types
18+
AddressType(..)
19+
, Credential(..)
20+
21+
-- * Classifying address types
22+
, asCollateral
23+
, addressSuitableForCollateral
24+
, addressTypeSuitableForCollateral
25+
26+
-- * Reading address types
27+
, addressTypeFromHeaderNibble
28+
, getAddressType
29+
, addressType
30+
31+
-- * Writing address types
32+
, addressTypeToHeaderNibble
33+
, putAddressType
34+
) where
35+
36+
import Prelude
37+
38+
import Cardano.Wallet.Primitive.Types.Address
39+
( Address (..) )
40+
import Cardano.Wallet.Primitive.Types.Coin
41+
( Coin )
42+
import Cardano.Wallet.Primitive.Types.Tx
43+
( TxOut (..) )
44+
import Data.Word
45+
( Word8 )
46+
import Data.Word.Odd
47+
( Word4 )
48+
49+
import qualified Cardano.Wallet.Primitive.Types.TokenBundle as TokenBundle
50+
import qualified Data.Binary.Get as B
51+
import qualified Data.Binary.Put as B
52+
import qualified Data.Bits as Bits
53+
import qualified Data.ByteString.Lazy as BL
54+
55+
-- In the realm of cardano-ledger-specs, we recognize the following types of
56+
-- addresses:
57+
-- (see https://hydra.iohk.io/build/6752483/download/1/ledger-spec.pdf):
58+
--
59+
-- | Address type | Payment Credential | Stake Credential | Header, first nibble |
60+
-- |--------------------+--------------------+------------------+----------------------|
61+
-- | Base address | keyhash | keyhash | 0000 |
62+
-- | | scripthash | keyhash | 0001 |
63+
-- | | keyhash | scripthash | 0010 |
64+
-- | | scripthash | scripthash | 0011 |
65+
-- | Pointer address | keyhash | ptr | 0100 |
66+
-- | | scripthash | ptr | 0101 |
67+
-- | Enterprise address | keyhash | - | 0110 |
68+
-- | | scripthash | 0 | 0111 |
69+
-- | Bootstrap address | keyhash | - | 1000 |
70+
-- | Stake address | - | keyhash | 1110 |
71+
-- | | - | scripthash | 1111 |
72+
-- | Future formats | ? | ? | 1001-1101 |
73+
--
74+
-- We represent these types of addresses with the following data types:
75+
76+
-- | The type of the address.
77+
data AddressType
78+
= BaseAddress Credential Credential
79+
| PointerAddress Credential
80+
| EnterpriseAddress Credential
81+
| StakeAddress Credential
82+
| BootstrapAddress
83+
-- ^ A Bootstrap (a.k.a. Byron) address
84+
deriving (Eq, Show)
85+
86+
-- | The type of the credential used in an address.
87+
data Credential
88+
= CredentialKeyHash
89+
| CredentialScriptHash
90+
deriving (Eq, Show)
91+
92+
-- To parse the address type, we can inspect the first four bits (nibble) of the
93+
-- address:
94+
95+
-- | Construct an @AddressType@ from the binary representation.
96+
addressTypeFromHeaderNibble :: Word4 -> Maybe AddressType
97+
addressTypeFromHeaderNibble = \case
98+
0b0000 -> Just (BaseAddress CredentialKeyHash CredentialKeyHash)
99+
0b0001 -> Just (BaseAddress CredentialScriptHash CredentialKeyHash)
100+
0b0010 -> Just (BaseAddress CredentialKeyHash CredentialScriptHash)
101+
0b0011 -> Just (BaseAddress CredentialScriptHash CredentialScriptHash)
102+
0b0100 -> Just (PointerAddress CredentialKeyHash)
103+
0b0101 -> Just (PointerAddress CredentialScriptHash)
104+
0b0110 -> Just (EnterpriseAddress CredentialKeyHash)
105+
0b0111 -> Just (EnterpriseAddress CredentialScriptHash)
106+
0b1000 -> Just (BootstrapAddress)
107+
0b1110 -> Just (StakeAddress CredentialKeyHash)
108+
0b1111 -> Just (StakeAddress CredentialScriptHash)
109+
_ -> Nothing
110+
111+
-- | Get an AddressType from a binary stream.
112+
getAddressType :: B.Get AddressType
113+
getAddressType = do
114+
headerAndNetwork <- B.getWord8
115+
let headerNibble =
116+
fromIntegral @Word8 @Word4 (headerAndNetwork `Bits.shiftR` 4)
117+
maybe
118+
(fail "Unknown address type.")
119+
(pure)
120+
(addressTypeFromHeaderNibble headerNibble)
121+
122+
-- For testing and other purposes, it is also helpful to have a way of writing
123+
-- the AddressType back to a binary stream.
124+
125+
-- | Return the binary representation of an @AddressType@.
126+
addressTypeToHeaderNibble :: AddressType -> Word4
127+
addressTypeToHeaderNibble = \case
128+
BaseAddress CredentialKeyHash CredentialKeyHash -> 0b0000
129+
BaseAddress CredentialScriptHash CredentialKeyHash -> 0b0001
130+
BaseAddress CredentialKeyHash CredentialScriptHash -> 0b0010
131+
BaseAddress CredentialScriptHash CredentialScriptHash -> 0b0011
132+
PointerAddress CredentialKeyHash -> 0b0100
133+
PointerAddress CredentialScriptHash -> 0b0101
134+
EnterpriseAddress CredentialKeyHash -> 0b0110
135+
EnterpriseAddress CredentialScriptHash -> 0b0111
136+
BootstrapAddress -> 0b1000
137+
StakeAddress CredentialKeyHash -> 0b1110
138+
StakeAddress CredentialScriptHash -> 0b1111
139+
140+
-- | Write an AddressType to a binary stream.
141+
putAddressType :: AddressType -> B.Put
142+
putAddressType t =
143+
B.putWord8 $
144+
fromIntegral @Word4 @Word8 (addressTypeToHeaderNibble t) `Bits.shiftL` 4
145+
146+
-- | Indicates whether or not the given address is suitable for collateral.
147+
--
148+
addressSuitableForCollateral :: Address -> Bool
149+
addressSuitableForCollateral =
150+
maybe False addressTypeSuitableForCollateral . addressType
151+
152+
-- By inspecting the bit pattern of an Address, we can determine its address
153+
-- type.
154+
155+
-- | Get the address type of a given address.
156+
addressType :: Address -> Maybe AddressType
157+
addressType (Address bytes) =
158+
case B.runGetOrFail getAddressType (BL.fromStrict bytes) of
159+
Left _ ->
160+
Nothing
161+
Right (_, _, addrType) ->
162+
Just addrType
163+
164+
-- The funds associated with an address are considered suitable for use as
165+
-- collateral iff the payment credential column of that address is "key hash".
166+
167+
-- | A simple function which determines if an @AddressType@ is suitable for use
168+
-- as collateral. Only @AddressType@s with a "key hash" payment credential are
169+
-- considered suitable for use as collateral.
170+
addressTypeSuitableForCollateral :: AddressType -> Bool
171+
addressTypeSuitableForCollateral = \case
172+
BaseAddress CredentialKeyHash CredentialKeyHash -> True
173+
BaseAddress CredentialKeyHash CredentialScriptHash -> True
174+
BaseAddress CredentialScriptHash CredentialKeyHash -> False
175+
BaseAddress CredentialScriptHash CredentialScriptHash -> False
176+
PointerAddress CredentialKeyHash -> True
177+
PointerAddress CredentialScriptHash -> False
178+
EnterpriseAddress CredentialKeyHash -> True
179+
EnterpriseAddress CredentialScriptHash -> False
180+
StakeAddress CredentialKeyHash -> False
181+
StakeAddress CredentialScriptHash -> False
182+
BootstrapAddress -> True
183+
184+
-- | If the given @TxOut@ represents a UTxO that is suitable for use as
185+
-- a collateral input, returns @Just@ along with the total ADA value of the
186+
-- UTxO. Otherwise returns @Nothing@ if it is not a suitable collateral value.
187+
asCollateral
188+
:: TxOut
189+
-- ^ TxOut from a UTxO entry
190+
-> Maybe Coin
191+
-- ^ The total ADA value of that UTxO if it is suitable for collateral,
192+
-- otherwise Nothing.
193+
asCollateral txOut
194+
| addressSuitableForCollateral (address txOut) =
195+
TokenBundle.toCoin (tokens txOut)
196+
| otherwise =
197+
Nothing

Diff for: lib/core/test/unit/Cardano/Wallet/Primitive/CoinSelection/MA/RoundRobinSpec.hs

-6
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,6 @@ import Test.QuickCheck
164164
, Property
165165
, applyFun
166166
, arbitraryBoundedEnum
167-
, arbitrarySizedNatural
168167
, checkCoverage
169168
, choose
170169
, conjoin
@@ -178,7 +177,6 @@ import Test.QuickCheck
178177
, label
179178
, oneof
180179
, property
181-
, shrinkIntegral
182180
, shrinkList
183181
, sublistOf
184182
, suchThat
@@ -3480,10 +3478,6 @@ instance Arbitrary AssetId where
34803478
arbitrary = genAssetId
34813479
shrink = shrinkAssetId
34823480

3483-
instance Arbitrary Natural where
3484-
arbitrary = arbitrarySizedNatural
3485-
shrink = shrinkIntegral
3486-
34873481
instance Arbitrary MakeChangeData where
34883482
arbitrary = genMakeChangeData
34893483

0 commit comments

Comments
 (0)