Skip to content

Commit

Permalink
Replace fromIntegral with safer intCast and Finite constructor.
Browse files Browse the repository at this point in the history
Justification:

- Using `fromIntegral` can hide unsafe integral narrowing conversions.
- Using `intCast` eliminates this class of error statically.

When creating values of `Data.Interval.Extended`, we can use the
`Finite` constructor instead of `fromIntegral`.

The following expressions are equivalent:

> Finite @int 1000
Finite 1000

> fromIntegral 1000 :: Extended Int
Finite 1000

> Finite @int 1000 == fromIntegral 1000
True
  • Loading branch information
jonathanknowles committed Apr 29, 2022
1 parent 2f13c08 commit 4ee5534
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ import Cardano.Wallet.Primitive.Types.TokenQuantity
( TokenQuantity (..) )
import Cardano.Wallet.Util
( invariant )
import Data.IntCast
( intCast )
import Data.Interval
( Interval, (<=..<=) )
import Data.List.NonEmpty
Expand Down Expand Up @@ -218,12 +220,12 @@ toSlotInterval = \case
RequireSomeOf _ xs ->
concatMap toSlotInterval (filterOutSig xs)
ActiveFromSlot s ->
[fromIntegral s <=..<= maxSlot]
[I.Finite s <=..<= maxSlot]
ActiveUntilSlot s ->
[minSlot <=..<= fromIntegral s]
[minSlot <=..<= I.Finite s]
where
minSlot = fromIntegral $ minBound @Word64
maxSlot = fromIntegral $ maxBound @Word64
minSlot = I.Finite $ intCast $ minBound @Word64
maxSlot = I.Finite $ intCast $ maxBound @Word64
allSlots = minSlot <=..<= maxSlot

isNotSig = \case
Expand Down Expand Up @@ -256,4 +258,4 @@ withinSlotInterval (SlotNo from) (SlotNo to) =
L.any (txValidityInterval `I.isSubsetOf`)
where
txValidityInterval =
fromIntegral from <=..<= fromIntegral to
I.Finite (intCast from) <=..<= I.Finite (intCast to)
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ import Codec.Binary.Encoding
( fromBase16 )
import Data.Function
( (&) )
import Data.IntCast
( intCast )
import Data.Interval
( Interval, empty, (<=..<=) )
import Data.Text
Expand All @@ -68,13 +70,14 @@ import qualified Cardano.Address.Script as CA
import qualified Cardano.Wallet.Primitive.AddressDerivation.Shelley as Shelley
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BL
import qualified Data.Interval as I
import qualified Data.Text.Encoding as T

spec :: Spec
spec = do
parallel $ describe "Mint/Burn Policy key Address Derivation Properties" $ do
let minSlot = fromIntegral $ minBound @Word64
let maxSlot = fromIntegral $ maxBound @Word64
let minSlot = I.Finite $ intCast $ minBound @Word64
let maxSlot = I.Finite $ intCast $ maxBound @Word64
let hashKeyTxt :: Text
hashKeyTxt =
"deeae4e895d8d57378125ed4fd540f9bf245d59f7936a504379cfc1e"
Expand Down Expand Up @@ -109,25 +112,25 @@ spec = do
-- cardano-address CLI from test mnemonic
it "Unit tests for toSlotInterval" $ do
unit_toSlotInterval hashKey
[fromIntegral @Natural 0 <=..<= maxSlot]
[I.Finite @Natural 0 <=..<= maxSlot]

unit_toSlotInterval (RequireAllOf [hashKey, ActiveFromSlot 120])
[fromIntegral @Natural 120 <=..<= maxSlot]
[I.Finite @Natural 120 <=..<= maxSlot]

unit_toSlotInterval (RequireAllOf [hashKey, ActiveUntilSlot 120])
[minSlot <=..<= fromIntegral @Natural 120]
[minSlot <=..<= I.Finite @Natural 120]

unit_toSlotInterval (RequireAnyOf [hashKey, ActiveFromSlot 120])
[fromIntegral @Natural 120 <=..<= maxSlot]
[I.Finite @Natural 120 <=..<= maxSlot]

unit_toSlotInterval (RequireAnyOf [hashKey, ActiveUntilSlot 120])
[minSlot <=..<= fromIntegral @Natural 120]
[minSlot <=..<= I.Finite @Natural 120]

unit_toSlotInterval (RequireSomeOf 1 [hashKey, ActiveFromSlot 120])
[fromIntegral @Natural 120 <=..<= maxSlot]
[I.Finite @Natural 120 <=..<= maxSlot]

unit_toSlotInterval (RequireSomeOf 1 [hashKey, ActiveUntilSlot 120])
[minSlot <=..<= fromIntegral @Natural 120]
[minSlot <=..<= I.Finite @Natural 120]

unit_toSlotInterval
(RequireAllOf
Expand All @@ -136,7 +139,7 @@ spec = do
, ActiveUntilSlot 120
]
)
[fromIntegral @Natural 100 <=..<= fromIntegral @Natural 120]
[I.Finite @Natural 100 <=..<= I.Finite @Natural 120]

unit_toSlotInterval
(RequireAllOf
Expand All @@ -154,8 +157,8 @@ spec = do
, ActiveUntilSlot 100
]
)
[ fromIntegral @Natural 120 <=..<= maxSlot
, minSlot <=..<= fromIntegral @Natural 100
[ I.Finite @Natural 120 <=..<= maxSlot
, minSlot <=..<= I.Finite @Natural 100
]

unit_toSlotInterval
Expand All @@ -165,8 +168,8 @@ spec = do
, ActiveUntilSlot 100
]
)
[ fromIntegral @Natural 120 <=..<= maxSlot
, minSlot <=..<= fromIntegral @Natural 100
[ I.Finite @Natural 120 <=..<= maxSlot
, minSlot <=..<= I.Finite @Natural 100
]

it "Unit tests for withinSlotInterval" $ do
Expand Down

0 comments on commit 4ee5534

Please sign in to comment.