File tree 7 files changed +53
-3
lines changed
7 files changed +53
-3
lines changed Original file line number Diff line number Diff line change @@ -42,6 +42,7 @@ library
42
42
Cardano.Db.Run
43
43
Cardano.Db.Schema
44
44
Cardano.Db.Schema.Types
45
+ Cardano.Db.Schema.Orphans
45
46
Cardano.Db.Types
46
47
47
48
@@ -76,6 +77,7 @@ library
76
77
, transformers
77
78
-- This is never intended to run on non-POSIX systems.
78
79
, unix
80
+ , wide-word
79
81
80
82
executable cardano-db-tool
81
83
default-language : Haskell2010
@@ -133,7 +135,9 @@ test-suite test
133
135
, aeson
134
136
, cardano-db
135
137
, cardano-ledger
138
+ , persistent
136
139
, hedgehog
140
+ , wide-word
137
141
138
142
test-suite test-db
139
143
default-language : Haskell2010
Original file line number Diff line number Diff line change 16
16
17
17
module Cardano.Db.Schema where
18
18
19
+ import Cardano.Db.Schema.Orphans ()
20
+
19
21
import Data.ByteString.Char8 (ByteString )
20
22
import Data.Int (Int64 )
21
23
import Data.Text (Text )
22
24
import Data.Time.Clock (UTCTime )
23
25
import Data.Word (Word16 , Word64 )
26
+ import Data.WideWord.Word128 (Word128 )
24
27
25
28
-- Do not use explicit imports from this module as the imports can change
26
29
-- from version to version due to changes to the TH code in Persistent.
@@ -128,7 +131,7 @@ share
128
131
-- hold 204 times the total Lovelace distribution. The chance of that much being transacted
129
132
-- in a single epoch is relatively low.
130
133
Epoch
131
- outSum Word64 sqltype=outsum
134
+ outSum Word128 sqltype=word128
132
135
txCount Word64 sqltype=uinteger
133
136
blkCount Word64 sqltype=uinteger
134
137
no Word64 sqltype=uinteger
Original file line number Diff line number Diff line change
1
+ {-# LANGUAGE OverloadedStrings #-}
2
+
3
+ {-# OPTIONS_GHC -Wno-orphans #-}
4
+
5
+ module Cardano.Db.Schema.Orphans where
6
+
7
+ import Data.WideWord.Word128 (Word128 )
8
+
9
+ import qualified Data.Text as Text
10
+
11
+ import Database.Persist.Class (PersistField (.. ))
12
+ import Database.Persist.Types (PersistValue (.. ))
13
+
14
+
15
+ instance PersistField Word128 where
16
+ toPersistValue = PersistText . Text. pack . show
17
+ fromPersistValue (PersistText bs) = Right $ read (Text. unpack bs)
18
+ fromPersistValue x =
19
+ Left $ mconcat [ " Failed to parse Haskell type Word128: " , Text. pack (show x) ]
20
+
Original file line number Diff line number Diff line change @@ -9,6 +9,9 @@ import Cardano.Chain.Common (maxLovelaceVal)
9
9
10
10
import qualified Data.Aeson as Aeson
11
11
import Data.Word (Word64 )
12
+ import Data.WideWord.Word128 (Word128 (.. ))
13
+
14
+ import Database.Persist.Class (PersistField (.. ))
12
15
13
16
import Cardano.Db
14
17
@@ -24,6 +27,12 @@ prop_roundtrip_Ada_via_JSON =
24
27
mv <- H. forAll genAda
25
28
H. tripping mv Aeson. encode Aeson. eitherDecode
26
29
30
+ prop_roundtrip_Word128_PersistField :: Property
31
+ prop_roundtrip_Word128_PersistField =
32
+ H. withTests 5000 . H. property $ do
33
+ w128 <- H. forAll genWord128
34
+ H. tripping w128 toPersistValue fromPersistValue
35
+
27
36
-- -----------------------------------------------------------------------------
28
37
29
38
genAda :: Gen Ada
@@ -38,6 +47,12 @@ genAda =
38
47
, Gen. word64 (Range. linear (maxLovelaceVal - 5000 ) maxLovelaceVal) -- Near max.
39
48
]
40
49
50
+ genWord128 :: Gen Word128
51
+ genWord128 = Word128 <$> genWord64 <*> genWord64
52
+
53
+ genWord64 :: Gen Word64
54
+ genWord64 = Gen. word64 Range. constantBounded
55
+
41
56
-- -----------------------------------------------------------------------------
42
57
43
58
tests :: IO Bool
Original file line number Diff line number Diff line change @@ -61,3 +61,4 @@ library
61
61
, transformers
62
62
-- This is never intended to run on non-POSIX systems.
63
63
, unix
64
+ , wide-word
Original file line number Diff line number Diff line change 21
21
-- Stake addresses are a 28 byte hash prepended with a byte describing the address.
22
22
EXECUTE ' CREATE DOMAIN addr29type AS bytea CHECK (octet_length (VALUE) = 29);' ;
23
23
24
+ -- 'maxBound :: Word128' as a decimal has 39 digits, so we only need to check that it
25
+ -- is positive.
26
+ EXECUTE ' CREATE DOMAIN word128type AS numeric (38, 0) CHECK (VALUE >= 0);' ;
27
+
24
28
UPDATE " schema_version" SET stage_one = 1 ;
25
29
RAISE NOTICE ' DB has been migrated to stage_one version %' , next_version;
26
30
END IF;
Original file line number Diff line number Diff line change 9
9
SELECT stage_one + 1 INTO next_version FROM " schema_version" ;
10
10
IF next_version = 2 THEN
11
11
-- Used as the sum of tx outputs for an epoch.
12
- -- Need this to catch possible overflow.
13
- EXECUTE ' CREATE DOMAIN outsum AS bigint CHECK (VALUE >= 0);' ;
12
+ -- Persistent does not support more precision than 'Int64' (support for 'Word64'
13
+ -- is done as a 'cast' to/from 'Int64' resulting in values greater than
14
+ -- 'maxBound :: Int64' being represented in the database as negative values.
15
+ -- Instead we we use 'Word128'.
16
+ EXECUTE ' CREATE DOMAIN outsum AS word128type;' ;
14
17
15
18
UPDATE " schema_version" SET stage_one = next_version;
16
19
RAISE NOTICE ' DB has been migrated to stage_one version %' , next_version;
You can’t perform that action at this time.
0 commit comments