{-# LANGUAGE FlexibleContexts  #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase        #-}
module Haskoin.Store.Database.Reader
    ( -- * RocksDB Database Access
      DatabaseReader (..)
    , DatabaseReaderT
    , withDatabaseReader
    , addrTxCF
    , addrOutCF
    , txCF
    , spenderCF
    , unspentCF
    , blockCF
    , heightCF
    , balanceCF
    ) where

import           Conduit                      (lift, mapC, runConduit, sinkList,
                                               (.|))
import           Control.Monad.Except         (runExceptT, throwError)
import           Control.Monad.Reader         (ReaderT, ask, asks, runReaderT)
import           Data.Bits                    ((.&.))
import qualified Data.ByteString              as BS
import           Data.Default                 (def)
import           Data.Function                (on)
import           Data.List                    (sortBy)
import           Data.Maybe                   (fromMaybe)
import           Data.Serialize               (encode)
import           Data.Word                    (Word32, Word64)
import           Database.RocksDB             (ColumnFamily, Config (..),
                                               DB (..), withDBCF, withIterCF)
import           Database.RocksDB.Query       (insert, matching,
                                               matchingAsListCF, matchingSkip,
                                               retrieve, retrieveCF)
import           Haskoin                      (Address, BlockHash, BlockHeight,
                                               Network, OutPoint (..), TxHash,
                                               txHash)
import           Haskoin.Store.Common
import           Haskoin.Store.Data
import           Haskoin.Store.Database.Types
import           UnliftIO                     (MonadIO, MonadUnliftIO, liftIO)

type DatabaseReaderT = ReaderT DatabaseReader

data DatabaseReader =
    DatabaseReader
        { DatabaseReader -> DB
databaseHandle     :: !DB
        , DatabaseReader -> Word32
databaseMaxGap     :: !Word32
        , DatabaseReader -> Word32
databaseInitialGap :: !Word32
        , DatabaseReader -> Network
databaseNetwork    :: !Network
        }

dataVersion :: Word32
dataVersion :: Word32
dataVersion = 17

withDatabaseReader :: MonadUnliftIO m
                   => Network
                   -> Word32
                   -> Word32
                   -> FilePath
                   -> DatabaseReaderT m a
                   -> m a
withDatabaseReader :: Network
-> Word32 -> Word32 -> FilePath -> DatabaseReaderT m a -> m a
withDatabaseReader net :: Network
net igap :: Word32
igap gap :: Word32
gap dir :: FilePath
dir f :: DatabaseReaderT m a
f =
    FilePath -> Config -> [(FilePath, Config)] -> (DB -> m a) -> m a
forall (m :: * -> *) a.
MonadUnliftIO m =>
FilePath -> Config -> [(FilePath, Config)] -> (DB -> m a) -> m a
withDBCF FilePath
dir Config
cfg [(FilePath, Config)]
columnFamilyConfig ((DB -> m a) -> m a) -> (DB -> m a) -> m a
forall a b. (a -> b) -> a -> b
$ \db :: DB
db -> do
    let bdb :: DatabaseReader
bdb =
            $WDatabaseReader :: DB -> Word32 -> Word32 -> Network -> DatabaseReader
DatabaseReader
                { databaseHandle :: DB
databaseHandle = DB
db
                , databaseMaxGap :: Word32
databaseMaxGap = Word32
gap
                , databaseNetwork :: Network
databaseNetwork = Network
net
                , databaseInitialGap :: Word32
databaseInitialGap = Word32
igap
                }
    DatabaseReader -> m ()
forall (m :: * -> *). MonadIO m => DatabaseReader -> m ()
initRocksDB DatabaseReader
bdb
    DatabaseReaderT m a -> DatabaseReader -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT DatabaseReaderT m a
f DatabaseReader
bdb
  where
    cfg :: Config
cfg = Config
forall a. Default a => a
def{createIfMissing :: Bool
createIfMissing = Bool
True, maxFiles :: Maybe Int
maxFiles = Int -> Maybe Int
forall a. a -> Maybe a
Just (-1)}

columnFamilyConfig :: [(String, Config)]
columnFamilyConfig :: [(FilePath, Config)]
columnFamilyConfig =
          [ ("addr-tx",     Config
forall a. Default a => a
def{prefixLength :: Maybe Int
prefixLength = Int -> Maybe Int
forall a. a -> Maybe a
Just 22, bloomFilter :: Bool
bloomFilter = Bool
True})
          , ("addr-out",    Config
forall a. Default a => a
def{prefixLength :: Maybe Int
prefixLength = Int -> Maybe Int
forall a. a -> Maybe a
Just 22, bloomFilter :: Bool
bloomFilter = Bool
True})
          , ("tx",          Config
forall a. Default a => a
def{prefixLength :: Maybe Int
prefixLength = Int -> Maybe Int
forall a. a -> Maybe a
Just 33, bloomFilter :: Bool
bloomFilter = Bool
True})
          , ("spender",     Config
forall a. Default a => a
def{prefixLength :: Maybe Int
prefixLength = Int -> Maybe Int
forall a. a -> Maybe a
Just 33, bloomFilter :: Bool
bloomFilter = Bool
True})
          , ("unspent",     Config
forall a. Default a => a
def{prefixLength :: Maybe Int
prefixLength = Int -> Maybe Int
forall a. a -> Maybe a
Just 37, bloomFilter :: Bool
bloomFilter = Bool
True})
          , ("block",       Config
forall a. Default a => a
def{prefixLength :: Maybe Int
prefixLength = Int -> Maybe Int
forall a. a -> Maybe a
Just 33, bloomFilter :: Bool
bloomFilter = Bool
True})
          , ("height",      Config
forall a. Default a => a
def{prefixLength :: Maybe Int
prefixLength = Maybe Int
forall a. Maybe a
Nothing, bloomFilter :: Bool
bloomFilter = Bool
True})
          , ("balance",     Config
forall a. Default a => a
def{prefixLength :: Maybe Int
prefixLength = Int -> Maybe Int
forall a. a -> Maybe a
Just 22, bloomFilter :: Bool
bloomFilter = Bool
True})
          ]

addrTxCF :: DB -> ColumnFamily
addrTxCF :: DB -> ColumnFamily
addrTxCF = [ColumnFamily] -> ColumnFamily
forall a. [a] -> a
head ([ColumnFamily] -> ColumnFamily)
-> (DB -> [ColumnFamily]) -> DB -> ColumnFamily
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DB -> [ColumnFamily]
columnFamilies

addrOutCF :: DB -> ColumnFamily
addrOutCF :: DB -> ColumnFamily
addrOutCF db :: DB
db = DB -> [ColumnFamily]
columnFamilies DB
db [ColumnFamily] -> Int -> ColumnFamily
forall a. [a] -> Int -> a
!! 1

txCF :: DB -> ColumnFamily
txCF :: DB -> ColumnFamily
txCF db :: DB
db = DB -> [ColumnFamily]
columnFamilies DB
db [ColumnFamily] -> Int -> ColumnFamily
forall a. [a] -> Int -> a
!! 2

spenderCF :: DB -> ColumnFamily
spenderCF :: DB -> ColumnFamily
spenderCF db :: DB
db = DB -> [ColumnFamily]
columnFamilies DB
db [ColumnFamily] -> Int -> ColumnFamily
forall a. [a] -> Int -> a
!! 3

unspentCF :: DB -> ColumnFamily
unspentCF :: DB -> ColumnFamily
unspentCF db :: DB
db = DB -> [ColumnFamily]
columnFamilies DB
db [ColumnFamily] -> Int -> ColumnFamily
forall a. [a] -> Int -> a
!! 4

blockCF :: DB -> ColumnFamily
blockCF :: DB -> ColumnFamily
blockCF db :: DB
db = DB -> [ColumnFamily]
columnFamilies DB
db [ColumnFamily] -> Int -> ColumnFamily
forall a. [a] -> Int -> a
!! 5

heightCF :: DB -> ColumnFamily
heightCF :: DB -> ColumnFamily
heightCF db :: DB
db = DB -> [ColumnFamily]
columnFamilies DB
db [ColumnFamily] -> Int -> ColumnFamily
forall a. [a] -> Int -> a
!! 6

balanceCF :: DB -> ColumnFamily
balanceCF :: DB -> ColumnFamily
balanceCF db :: DB
db = DB -> [ColumnFamily]
columnFamilies DB
db [ColumnFamily] -> Int -> ColumnFamily
forall a. [a] -> Int -> a
!! 7

initRocksDB :: MonadIO m => DatabaseReader -> m ()
initRocksDB :: DatabaseReader -> m ()
initRocksDB DatabaseReader{databaseHandle :: DatabaseReader -> DB
databaseHandle = DB
db} = do
    Either FilePath ()
e <-
        ExceptT FilePath m () -> m (Either FilePath ())
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT (ExceptT FilePath m () -> m (Either FilePath ()))
-> ExceptT FilePath m () -> m (Either FilePath ())
forall a b. (a -> b) -> a -> b
$
        DB -> VersionKey -> ExceptT FilePath m (Maybe Word32)
forall (m :: * -> *) key value.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
DB -> key -> m (Maybe value)
retrieve DB
db VersionKey
VersionKey ExceptT FilePath m (Maybe Word32)
-> (Maybe Word32 -> ExceptT FilePath m ()) -> ExceptT FilePath m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
            Just v :: Word32
v
                | Word32
v Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
dataVersion -> () -> ExceptT FilePath m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
                | Bool
otherwise -> FilePath -> ExceptT FilePath m ()
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError "Incorrect RocksDB database version"
            Nothing -> DB -> ExceptT FilePath m ()
forall (m :: * -> *). MonadIO m => DB -> m ()
setInitRocksDB DB
db
    case Either FilePath ()
e of
        Left s :: FilePath
s   -> FilePath -> m ()
forall a. HasCallStack => FilePath -> a
error FilePath
s
        Right () -> () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

setInitRocksDB :: MonadIO m => DB -> m ()
setInitRocksDB :: DB -> m ()
setInitRocksDB db :: DB
db = DB -> VersionKey -> Word32 -> m ()
forall (m :: * -> *) key value.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
DB -> key -> value -> m ()
insert DB
db VersionKey
VersionKey Word32
dataVersion

getBestDatabaseReader :: MonadIO m => DatabaseReader -> m (Maybe BlockHash)
getBestDatabaseReader :: DatabaseReader -> m (Maybe BlockHash)
getBestDatabaseReader DatabaseReader{databaseHandle :: DatabaseReader -> DB
databaseHandle = DB
db} =
    DB -> BestKey -> m (Maybe BlockHash)
forall (m :: * -> *) key value.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
DB -> key -> m (Maybe value)
retrieve DB
db BestKey
BestKey

getBlocksAtHeightDB :: MonadIO m => BlockHeight -> DatabaseReader -> m [BlockHash]
getBlocksAtHeightDB :: Word32 -> DatabaseReader -> m [BlockHash]
getBlocksAtHeightDB h :: Word32
h DatabaseReader{databaseHandle :: DatabaseReader -> DB
databaseHandle = DB
db} =
    DB -> ColumnFamily -> HeightKey -> m (Maybe [BlockHash])
forall (m :: * -> *) key value.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
DB -> ColumnFamily -> key -> m (Maybe value)
retrieveCF DB
db (DB -> ColumnFamily
heightCF DB
db) (Word32 -> HeightKey
HeightKey Word32
h) m (Maybe [BlockHash])
-> (Maybe [BlockHash] -> m [BlockHash]) -> m [BlockHash]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Nothing -> [BlockHash] -> m [BlockHash]
forall (m :: * -> *) a. Monad m => a -> m a
return []
        Just ls :: [BlockHash]
ls -> [BlockHash] -> m [BlockHash]
forall (m :: * -> *) a. Monad m => a -> m a
return [BlockHash]
ls

getDatabaseReader :: MonadIO m => BlockHash -> DatabaseReader -> m (Maybe BlockData)
getDatabaseReader :: BlockHash -> DatabaseReader -> m (Maybe BlockData)
getDatabaseReader h :: BlockHash
h DatabaseReader{databaseHandle :: DatabaseReader -> DB
databaseHandle = DB
db} =
    DB -> ColumnFamily -> BlockKey -> m (Maybe BlockData)
forall (m :: * -> *) key value.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
DB -> ColumnFamily -> key -> m (Maybe value)
retrieveCF DB
db (DB -> ColumnFamily
blockCF DB
db) (BlockHash -> BlockKey
BlockKey BlockHash
h)

getTxDataDB :: MonadIO m => TxHash -> DatabaseReader -> m (Maybe TxData)
getTxDataDB :: TxHash -> DatabaseReader -> m (Maybe TxData)
getTxDataDB th :: TxHash
th DatabaseReader{databaseHandle :: DatabaseReader -> DB
databaseHandle = DB
db} =
    DB -> ColumnFamily -> TxKey -> m (Maybe TxData)
forall (m :: * -> *) key value.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
DB -> ColumnFamily -> key -> m (Maybe value)
retrieveCF DB
db (DB -> ColumnFamily
txCF DB
db) (TxHash -> TxKey
TxKey TxHash
th)

getNumTxDataDB :: MonadIO m => Word64 -> DatabaseReader -> m [TxData]
getNumTxDataDB :: Word64 -> DatabaseReader -> m [TxData]
getNumTxDataDB i :: Word64
i r :: DatabaseReader
r@DatabaseReader{databaseHandle :: DatabaseReader -> DB
databaseHandle = DB
db} = do
    let (sk :: (Word32, Word16)
sk, w :: Word8
w) = Word64 -> ((Word32, Word16), Word8)
decodeTxKey Word64
i
    [(TxKey, TxData)]
ls <- IO [(TxKey, TxData)] -> m [(TxKey, TxData)]
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [(TxKey, TxData)] -> m [(TxKey, TxData)])
-> IO [(TxKey, TxData)] -> m [(TxKey, TxData)]
forall a b. (a -> b) -> a -> b
$ DB -> ColumnFamily -> TxKey -> IO [(TxKey, TxData)]
forall (m :: * -> *) key value.
(MonadUnliftIO m, KeyValue key value, Serialize key,
 Serialize value) =>
DB -> ColumnFamily -> key -> m [(key, value)]
matchingAsListCF DB
db (DB -> ColumnFamily
txCF DB
db) ((Word32, Word16) -> TxKey
TxKeyS (Word32, Word16)
sk)
    let f :: TxData -> Bool
f t :: TxData
t = let bs :: ByteString
bs = TxHash -> ByteString
forall a. Serialize a => a -> ByteString
encode (TxHash -> ByteString) -> TxHash -> ByteString
forall a b. (a -> b) -> a -> b
$ Tx -> TxHash
txHash (TxData -> Tx
txData TxData
t)
                  b :: Word8
b = ByteString -> Word8
BS.head (Int -> ByteString -> ByteString
BS.drop 6 ByteString
bs)
                  w' :: Word8
w' = Word8
b Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. 0xf8
              in Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
w'
    [TxData] -> m [TxData]
forall (m :: * -> *) a. Monad m => a -> m a
return ([TxData] -> m [TxData]) -> [TxData] -> m [TxData]
forall a b. (a -> b) -> a -> b
$ (TxData -> Bool) -> [TxData] -> [TxData]
forall a. (a -> Bool) -> [a] -> [a]
filter TxData -> Bool
f ([TxData] -> [TxData]) -> [TxData] -> [TxData]
forall a b. (a -> b) -> a -> b
$ ((TxKey, TxData) -> TxData) -> [(TxKey, TxData)] -> [TxData]
forall a b. (a -> b) -> [a] -> [b]
map (TxKey, TxData) -> TxData
forall a b. (a, b) -> b
snd [(TxKey, TxData)]
ls

getSpenderDB :: MonadIO m => OutPoint -> DatabaseReader -> m (Maybe Spender)
getSpenderDB :: OutPoint -> DatabaseReader -> m (Maybe Spender)
getSpenderDB op :: OutPoint
op DatabaseReader{databaseHandle :: DatabaseReader -> DB
databaseHandle = DB
db} =
    DB -> ColumnFamily -> SpenderKey -> m (Maybe Spender)
forall (m :: * -> *) key value.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
DB -> ColumnFamily -> key -> m (Maybe value)
retrieveCF DB
db (DB -> ColumnFamily
spenderCF DB
db) (SpenderKey -> m (Maybe Spender))
-> SpenderKey -> m (Maybe Spender)
forall a b. (a -> b) -> a -> b
$ OutPoint -> SpenderKey
SpenderKey OutPoint
op

getBalanceDB :: MonadIO m => Address -> DatabaseReader -> m (Maybe Balance)
getBalanceDB :: Address -> DatabaseReader -> m (Maybe Balance)
getBalanceDB a :: Address
a DatabaseReader{databaseHandle :: DatabaseReader -> DB
databaseHandle = DB
db} =
    (BalVal -> Balance) -> Maybe BalVal -> Maybe Balance
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Address -> BalVal -> Balance
valToBalance Address
a) (Maybe BalVal -> Maybe Balance)
-> m (Maybe BalVal) -> m (Maybe Balance)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DB -> ColumnFamily -> BalKey -> m (Maybe BalVal)
forall (m :: * -> *) key value.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
DB -> ColumnFamily -> key -> m (Maybe value)
retrieveCF DB
db (DB -> ColumnFamily
balanceCF DB
db) (Address -> BalKey
BalKey Address
a)

getMempoolDB :: MonadIO m => DatabaseReader -> m [(UnixTime, TxHash)]
getMempoolDB :: DatabaseReader -> m [(Word64, TxHash)]
getMempoolDB DatabaseReader{databaseHandle :: DatabaseReader -> DB
databaseHandle = DB
db} =
    [(Word64, TxHash)]
-> Maybe [(Word64, TxHash)] -> [(Word64, TxHash)]
forall a. a -> Maybe a -> a
fromMaybe [] (Maybe [(Word64, TxHash)] -> [(Word64, TxHash)])
-> m (Maybe [(Word64, TxHash)]) -> m [(Word64, TxHash)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DB -> MemKey -> m (Maybe [(Word64, TxHash)])
forall (m :: * -> *) key value.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
DB -> key -> m (Maybe value)
retrieve DB
db MemKey
MemKey

getAddressesTxsDB ::
       MonadIO m
    => [Address]
    -> Limits
    -> DatabaseReader
    -> m [TxRef]
getAddressesTxsDB :: [Address] -> Limits -> DatabaseReader -> m [TxRef]
getAddressesTxsDB addrs :: [Address]
addrs limits :: Limits
limits db :: DatabaseReader
db = do
    [TxRef]
ts <- [[TxRef]] -> [TxRef]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[TxRef]] -> [TxRef]) -> m [[TxRef]] -> m [TxRef]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Address -> m [TxRef]) -> [Address] -> m [[TxRef]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\a :: Address
a -> Address -> Limits -> DatabaseReader -> m [TxRef]
forall (m :: * -> *).
MonadIO m =>
Address -> Limits -> DatabaseReader -> m [TxRef]
getAddressTxsDB Address
a (Limits -> Limits
deOffset Limits
limits) DatabaseReader
db) [Address]
addrs
    let ts' :: [TxRef]
ts' = (TxRef -> TxRef -> Ordering) -> [TxRef] -> [TxRef]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy ((BlockRef -> BlockRef -> Ordering)
-> BlockRef -> BlockRef -> Ordering
forall a b c. (a -> b -> c) -> b -> a -> c
flip BlockRef -> BlockRef -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (BlockRef -> BlockRef -> Ordering)
-> (TxRef -> BlockRef) -> TxRef -> TxRef -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` TxRef -> BlockRef
txRefBlock) ([TxRef] -> [TxRef]
forall a. (Eq a, Hashable a) => [a] -> [a]
nub' [TxRef]
ts)
    [TxRef] -> m [TxRef]
forall (m :: * -> *) a. Monad m => a -> m a
return ([TxRef] -> m [TxRef]) -> [TxRef] -> m [TxRef]
forall a b. (a -> b) -> a -> b
$ Limits -> [TxRef] -> [TxRef]
forall a. Limits -> [a] -> [a]
applyLimits Limits
limits [TxRef]
ts'

getAddressTxsDB ::
       MonadIO m
    => Address
    -> Limits
    -> DatabaseReader
    -> m [TxRef]
getAddressTxsDB :: Address -> Limits -> DatabaseReader -> m [TxRef]
getAddressTxsDB a :: Address
a limits :: Limits
limits bdb :: DatabaseReader
bdb@DatabaseReader{databaseHandle :: DatabaseReader -> DB
databaseHandle = DB
db} =
    IO [TxRef] -> m [TxRef]
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [TxRef] -> m [TxRef]) -> IO [TxRef] -> m [TxRef]
forall a b. (a -> b) -> a -> b
$ DB -> ColumnFamily -> (Iterator -> IO [TxRef]) -> IO [TxRef]
forall (m :: * -> *) a.
MonadUnliftIO m =>
DB -> ColumnFamily -> (Iterator -> m a) -> m a
withIterCF DB
db (DB -> ColumnFamily
addrTxCF DB
db) ((Iterator -> IO [TxRef]) -> IO [TxRef])
-> (Iterator -> IO [TxRef]) -> IO [TxRef]
forall a b. (a -> b) -> a -> b
$ \it :: Iterator
it -> ConduitT () Void IO [TxRef] -> IO [TxRef]
forall (m :: * -> *) r. Monad m => ConduitT () Void m r -> m r
runConduit (ConduitT () Void IO [TxRef] -> IO [TxRef])
-> ConduitT () Void IO [TxRef] -> IO [TxRef]
forall a b. (a -> b) -> a -> b
$
    Iterator -> ConduitT () (AddrTxKey, ()) IO ()
forall (m :: * -> *) value i.
(MonadIO m, KeyValue AddrTxKey value, Serialize value) =>
Iterator -> ConduitT i (AddrTxKey, value) m ()
x Iterator
it ConduitT () (AddrTxKey, ()) IO ()
-> ConduitM (AddrTxKey, ()) Void IO [TxRef]
-> ConduitT () Void IO [TxRef]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.| Limits -> ConduitT (AddrTxKey, ()) (AddrTxKey, ()) IO ()
forall (m :: * -> *) i. Monad m => Limits -> ConduitT i i m ()
applyLimitsC Limits
limits ConduitT (AddrTxKey, ()) (AddrTxKey, ()) IO ()
-> ConduitM (AddrTxKey, ()) Void IO [TxRef]
-> ConduitM (AddrTxKey, ()) Void IO [TxRef]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.| ((AddrTxKey, ()) -> TxRef) -> ConduitT (AddrTxKey, ()) TxRef IO ()
forall (m :: * -> *) a b. Monad m => (a -> b) -> ConduitT a b m ()
mapC ((AddrTxKey -> () -> TxRef) -> (AddrTxKey, ()) -> TxRef
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry AddrTxKey -> () -> TxRef
f) ConduitT (AddrTxKey, ()) TxRef IO ()
-> ConduitM TxRef Void IO [TxRef]
-> ConduitM (AddrTxKey, ()) Void IO [TxRef]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.| ConduitM TxRef Void IO [TxRef]
forall (m :: * -> *) a o. Monad m => ConduitT a o m [a]
sinkList
  where
    x :: Iterator -> ConduitT i (AddrTxKey, value) m ()
x it :: Iterator
it =
        case Limits -> Maybe Start
start Limits
limits of
            Nothing -> Iterator -> AddrTxKey -> ConduitT i (AddrTxKey, value) m ()
forall (m :: * -> *) key value i.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
Iterator -> key -> ConduitT i (key, value) m ()
matching Iterator
it (Address -> AddrTxKey
AddrTxKeyA Address
a)
            Just (AtTx txh :: TxHash
txh) ->
                m (Maybe TxData) -> ConduitT i (AddrTxKey, value) m (Maybe TxData)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (TxHash -> DatabaseReader -> m (Maybe TxData)
forall (m :: * -> *).
MonadIO m =>
TxHash -> DatabaseReader -> m (Maybe TxData)
getTxDataDB TxHash
txh DatabaseReader
bdb) ConduitT i (AddrTxKey, value) m (Maybe TxData)
-> (Maybe TxData -> ConduitT i (AddrTxKey, value) m ())
-> ConduitT i (AddrTxKey, value) m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
                    Just TxData {txDataBlock :: TxData -> BlockRef
txDataBlock = b :: BlockRef
b@BlockRef {}} ->
                        Iterator
-> AddrTxKey -> AddrTxKey -> ConduitT i (AddrTxKey, value) m ()
forall (m :: * -> *) key value i.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
Iterator -> key -> key -> ConduitT i (key, value) m ()
matchingSkip Iterator
it (Address -> AddrTxKey
AddrTxKeyA Address
a) (Address -> BlockRef -> AddrTxKey
AddrTxKeyB Address
a BlockRef
b)
                    _ -> Iterator -> AddrTxKey -> ConduitT i (AddrTxKey, value) m ()
forall (m :: * -> *) key value i.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
Iterator -> key -> ConduitT i (key, value) m ()
matching Iterator
it (Address -> AddrTxKey
AddrTxKeyA Address
a)
            Just (AtBlock bh :: Word32
bh) ->
                Iterator
-> AddrTxKey -> AddrTxKey -> ConduitT i (AddrTxKey, value) m ()
forall (m :: * -> *) key value i.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
Iterator -> key -> key -> ConduitT i (key, value) m ()
matchingSkip
                    Iterator
it
                    (Address -> AddrTxKey
AddrTxKeyA Address
a)
                    (Address -> BlockRef -> AddrTxKey
AddrTxKeyB Address
a (Word32 -> Word32 -> BlockRef
BlockRef Word32
bh Word32
forall a. Bounded a => a
maxBound))
    f :: AddrTxKey -> () -> TxRef
f AddrTxKey {addrTxKeyT :: AddrTxKey -> TxRef
addrTxKeyT = TxRef
t} () = TxRef
t
    f _ _                           = TxRef
forall a. HasCallStack => a
undefined

getUnspentDB :: MonadIO m => OutPoint -> DatabaseReader -> m (Maybe Unspent)
getUnspentDB :: OutPoint -> DatabaseReader -> m (Maybe Unspent)
getUnspentDB p :: OutPoint
p DatabaseReader{databaseHandle :: DatabaseReader -> DB
databaseHandle = DB
db} =
    (UnspentVal -> Unspent) -> Maybe UnspentVal -> Maybe Unspent
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (OutPoint -> UnspentVal -> Unspent
valToUnspent OutPoint
p) (Maybe UnspentVal -> Maybe Unspent)
-> m (Maybe UnspentVal) -> m (Maybe Unspent)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DB -> ColumnFamily -> UnspentKey -> m (Maybe UnspentVal)
forall (m :: * -> *) key value.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
DB -> ColumnFamily -> key -> m (Maybe value)
retrieveCF DB
db (DB -> ColumnFamily
unspentCF DB
db) (OutPoint -> UnspentKey
UnspentKey OutPoint
p)

getAddressesUnspentsDB ::
       MonadIO m
    => [Address]
    -> Limits
    -> DatabaseReader
    -> m [Unspent]
getAddressesUnspentsDB :: [Address] -> Limits -> DatabaseReader -> m [Unspent]
getAddressesUnspentsDB addrs :: [Address]
addrs limits :: Limits
limits bdb :: DatabaseReader
bdb = do
    [Unspent]
us <-
        [[Unspent]] -> [Unspent]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Unspent]] -> [Unspent]) -> m [[Unspent]] -> m [Unspent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
        (Address -> m [Unspent]) -> [Address] -> m [[Unspent]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\a :: Address
a -> Address -> Limits -> DatabaseReader -> m [Unspent]
forall (m :: * -> *).
MonadIO m =>
Address -> Limits -> DatabaseReader -> m [Unspent]
getAddressUnspentsDB Address
a (Limits -> Limits
deOffset Limits
limits) DatabaseReader
bdb) [Address]
addrs
    let us' :: [Unspent]
us' = (Unspent -> Unspent -> Ordering) -> [Unspent] -> [Unspent]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy ((BlockRef -> BlockRef -> Ordering)
-> BlockRef -> BlockRef -> Ordering
forall a b c. (a -> b -> c) -> b -> a -> c
flip BlockRef -> BlockRef -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (BlockRef -> BlockRef -> Ordering)
-> (Unspent -> BlockRef) -> Unspent -> Unspent -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Unspent -> BlockRef
unspentBlock) ([Unspent] -> [Unspent]
forall a. (Eq a, Hashable a) => [a] -> [a]
nub' [Unspent]
us)
    [Unspent] -> m [Unspent]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Unspent] -> m [Unspent]) -> [Unspent] -> m [Unspent]
forall a b. (a -> b) -> a -> b
$ Limits -> [Unspent] -> [Unspent]
forall a. Limits -> [a] -> [a]
applyLimits Limits
limits [Unspent]
us'

getAddressUnspentsDB ::
       MonadIO m
    => Address
    -> Limits
    -> DatabaseReader
    -> m [Unspent]
getAddressUnspentsDB :: Address -> Limits -> DatabaseReader -> m [Unspent]
getAddressUnspentsDB a :: Address
a limits :: Limits
limits bdb :: DatabaseReader
bdb@DatabaseReader{databaseHandle :: DatabaseReader -> DB
databaseHandle = DB
db} =
    IO [Unspent] -> m [Unspent]
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [Unspent] -> m [Unspent]) -> IO [Unspent] -> m [Unspent]
forall a b. (a -> b) -> a -> b
$ DB -> ColumnFamily -> (Iterator -> IO [Unspent]) -> IO [Unspent]
forall (m :: * -> *) a.
MonadUnliftIO m =>
DB -> ColumnFamily -> (Iterator -> m a) -> m a
withIterCF DB
db (DB -> ColumnFamily
addrOutCF DB
db) ((Iterator -> IO [Unspent]) -> IO [Unspent])
-> (Iterator -> IO [Unspent]) -> IO [Unspent]
forall a b. (a -> b) -> a -> b
$ \it :: Iterator
it -> ConduitT () Void IO [Unspent] -> IO [Unspent]
forall (m :: * -> *) r. Monad m => ConduitT () Void m r -> m r
runConduit (ConduitT () Void IO [Unspent] -> IO [Unspent])
-> ConduitT () Void IO [Unspent] -> IO [Unspent]
forall a b. (a -> b) -> a -> b
$
    Iterator -> ConduitT () (AddrOutKey, OutVal) IO ()
forall (m :: * -> *) value i.
(MonadIO m, KeyValue AddrOutKey value, Serialize value) =>
Iterator -> ConduitT i (AddrOutKey, value) m ()
x Iterator
it ConduitT () (AddrOutKey, OutVal) IO ()
-> ConduitM (AddrOutKey, OutVal) Void IO [Unspent]
-> ConduitT () Void IO [Unspent]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.| Limits -> ConduitT (AddrOutKey, OutVal) (AddrOutKey, OutVal) IO ()
forall (m :: * -> *) i. Monad m => Limits -> ConduitT i i m ()
applyLimitsC Limits
limits ConduitT (AddrOutKey, OutVal) (AddrOutKey, OutVal) IO ()
-> ConduitM (AddrOutKey, OutVal) Void IO [Unspent]
-> ConduitM (AddrOutKey, OutVal) Void IO [Unspent]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.| ((AddrOutKey, OutVal) -> Unspent)
-> ConduitT (AddrOutKey, OutVal) Unspent IO ()
forall (m :: * -> *) a b. Monad m => (a -> b) -> ConduitT a b m ()
mapC ((AddrOutKey -> OutVal -> Unspent)
-> (AddrOutKey, OutVal) -> Unspent
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry AddrOutKey -> OutVal -> Unspent
toUnspent) ConduitT (AddrOutKey, OutVal) Unspent IO ()
-> ConduitM Unspent Void IO [Unspent]
-> ConduitM (AddrOutKey, OutVal) Void IO [Unspent]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.| ConduitM Unspent Void IO [Unspent]
forall (m :: * -> *) a o. Monad m => ConduitT a o m [a]
sinkList
  where
    x :: Iterator -> ConduitT i (AddrOutKey, value) m ()
x it :: Iterator
it = case Limits -> Maybe Start
start Limits
limits of
        Nothing ->
            Iterator -> AddrOutKey -> ConduitT i (AddrOutKey, value) m ()
forall (m :: * -> *) key value i.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
Iterator -> key -> ConduitT i (key, value) m ()
matching Iterator
it (Address -> AddrOutKey
AddrOutKeyA Address
a)
        Just (AtBlock h :: Word32
h) ->
            Iterator
-> AddrOutKey -> AddrOutKey -> ConduitT i (AddrOutKey, value) m ()
forall (m :: * -> *) key value i.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
Iterator -> key -> key -> ConduitT i (key, value) m ()
matchingSkip
                Iterator
it
                (Address -> AddrOutKey
AddrOutKeyA Address
a)
                (Address -> BlockRef -> AddrOutKey
AddrOutKeyB Address
a (Word32 -> Word32 -> BlockRef
BlockRef Word32
h Word32
forall a. Bounded a => a
maxBound))
        Just (AtTx txh :: TxHash
txh) ->
            m (Maybe TxData) -> ConduitT i (AddrOutKey, value) m (Maybe TxData)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (TxHash -> DatabaseReader -> m (Maybe TxData)
forall (m :: * -> *).
MonadIO m =>
TxHash -> DatabaseReader -> m (Maybe TxData)
getTxDataDB TxHash
txh DatabaseReader
bdb) ConduitT i (AddrOutKey, value) m (Maybe TxData)
-> (Maybe TxData -> ConduitT i (AddrOutKey, value) m ())
-> ConduitT i (AddrOutKey, value) m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
                Just TxData {txDataBlock :: TxData -> BlockRef
txDataBlock = b :: BlockRef
b@BlockRef {}} ->
                    Iterator
-> AddrOutKey -> AddrOutKey -> ConduitT i (AddrOutKey, value) m ()
forall (m :: * -> *) key value i.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
Iterator -> key -> key -> ConduitT i (key, value) m ()
matchingSkip Iterator
it (Address -> AddrOutKey
AddrOutKeyA Address
a) (Address -> BlockRef -> AddrOutKey
AddrOutKeyB Address
a BlockRef
b)
                _ -> Iterator -> AddrOutKey -> ConduitT i (AddrOutKey, value) m ()
forall (m :: * -> *) key value i.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
Iterator -> key -> ConduitT i (key, value) m ()
matching Iterator
it (Address -> AddrOutKey
AddrOutKeyA Address
a)

instance MonadIO m => StoreReadBase (DatabaseReaderT m) where
    getNetwork :: DatabaseReaderT m Network
getNetwork = (DatabaseReader -> Network) -> DatabaseReaderT m Network
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks DatabaseReader -> Network
databaseNetwork
    getTxData :: TxHash -> DatabaseReaderT m (Maybe TxData)
getTxData t :: TxHash
t = ReaderT DatabaseReader m DatabaseReader
forall r (m :: * -> *). MonadReader r m => m r
ask ReaderT DatabaseReader m DatabaseReader
-> (DatabaseReader -> DatabaseReaderT m (Maybe TxData))
-> DatabaseReaderT m (Maybe TxData)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= TxHash -> DatabaseReader -> DatabaseReaderT m (Maybe TxData)
forall (m :: * -> *).
MonadIO m =>
TxHash -> DatabaseReader -> m (Maybe TxData)
getTxDataDB TxHash
t
    getSpender :: OutPoint -> DatabaseReaderT m (Maybe Spender)
getSpender p :: OutPoint
p = ReaderT DatabaseReader m DatabaseReader
forall r (m :: * -> *). MonadReader r m => m r
ask ReaderT DatabaseReader m DatabaseReader
-> (DatabaseReader -> DatabaseReaderT m (Maybe Spender))
-> DatabaseReaderT m (Maybe Spender)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= OutPoint -> DatabaseReader -> DatabaseReaderT m (Maybe Spender)
forall (m :: * -> *).
MonadIO m =>
OutPoint -> DatabaseReader -> m (Maybe Spender)
getSpenderDB OutPoint
p
    getUnspent :: OutPoint -> DatabaseReaderT m (Maybe Unspent)
getUnspent a :: OutPoint
a = ReaderT DatabaseReader m DatabaseReader
forall r (m :: * -> *). MonadReader r m => m r
ask ReaderT DatabaseReader m DatabaseReader
-> (DatabaseReader -> DatabaseReaderT m (Maybe Unspent))
-> DatabaseReaderT m (Maybe Unspent)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= OutPoint -> DatabaseReader -> DatabaseReaderT m (Maybe Unspent)
forall (m :: * -> *).
MonadIO m =>
OutPoint -> DatabaseReader -> m (Maybe Unspent)
getUnspentDB OutPoint
a
    getBalance :: Address -> DatabaseReaderT m (Maybe Balance)
getBalance a :: Address
a = ReaderT DatabaseReader m DatabaseReader
forall r (m :: * -> *). MonadReader r m => m r
ask ReaderT DatabaseReader m DatabaseReader
-> (DatabaseReader -> DatabaseReaderT m (Maybe Balance))
-> DatabaseReaderT m (Maybe Balance)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Address -> DatabaseReader -> DatabaseReaderT m (Maybe Balance)
forall (m :: * -> *).
MonadIO m =>
Address -> DatabaseReader -> m (Maybe Balance)
getBalanceDB Address
a
    getMempool :: DatabaseReaderT m [(Word64, TxHash)]
getMempool = ReaderT DatabaseReader m DatabaseReader
forall r (m :: * -> *). MonadReader r m => m r
ask ReaderT DatabaseReader m DatabaseReader
-> (DatabaseReader -> DatabaseReaderT m [(Word64, TxHash)])
-> DatabaseReaderT m [(Word64, TxHash)]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= DatabaseReader -> DatabaseReaderT m [(Word64, TxHash)]
forall (m :: * -> *).
MonadIO m =>
DatabaseReader -> m [(Word64, TxHash)]
getMempoolDB
    getBestBlock :: DatabaseReaderT m (Maybe BlockHash)
getBestBlock = ReaderT DatabaseReader m DatabaseReader
forall r (m :: * -> *). MonadReader r m => m r
ask ReaderT DatabaseReader m DatabaseReader
-> (DatabaseReader -> DatabaseReaderT m (Maybe BlockHash))
-> DatabaseReaderT m (Maybe BlockHash)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= DatabaseReader -> DatabaseReaderT m (Maybe BlockHash)
forall (m :: * -> *).
MonadIO m =>
DatabaseReader -> m (Maybe BlockHash)
getBestDatabaseReader
    getBlocksAtHeight :: Word32 -> DatabaseReaderT m [BlockHash]
getBlocksAtHeight h :: Word32
h = ReaderT DatabaseReader m DatabaseReader
forall r (m :: * -> *). MonadReader r m => m r
ask ReaderT DatabaseReader m DatabaseReader
-> (DatabaseReader -> DatabaseReaderT m [BlockHash])
-> DatabaseReaderT m [BlockHash]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Word32 -> DatabaseReader -> DatabaseReaderT m [BlockHash]
forall (m :: * -> *).
MonadIO m =>
Word32 -> DatabaseReader -> m [BlockHash]
getBlocksAtHeightDB Word32
h
    getBlock :: BlockHash -> DatabaseReaderT m (Maybe BlockData)
getBlock b :: BlockHash
b = ReaderT DatabaseReader m DatabaseReader
forall r (m :: * -> *). MonadReader r m => m r
ask ReaderT DatabaseReader m DatabaseReader
-> (DatabaseReader -> DatabaseReaderT m (Maybe BlockData))
-> DatabaseReaderT m (Maybe BlockData)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= BlockHash -> DatabaseReader -> DatabaseReaderT m (Maybe BlockData)
forall (m :: * -> *).
MonadIO m =>
BlockHash -> DatabaseReader -> m (Maybe BlockData)
getDatabaseReader BlockHash
b

instance MonadIO m => StoreReadExtra (DatabaseReaderT m) where
    getAddressesTxs :: [Address] -> Limits -> DatabaseReaderT m [TxRef]
getAddressesTxs as :: [Address]
as limits :: Limits
limits = ReaderT DatabaseReader m DatabaseReader
forall r (m :: * -> *). MonadReader r m => m r
ask ReaderT DatabaseReader m DatabaseReader
-> (DatabaseReader -> DatabaseReaderT m [TxRef])
-> DatabaseReaderT m [TxRef]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [Address] -> Limits -> DatabaseReader -> DatabaseReaderT m [TxRef]
forall (m :: * -> *).
MonadIO m =>
[Address] -> Limits -> DatabaseReader -> m [TxRef]
getAddressesTxsDB [Address]
as Limits
limits
    getAddressesUnspents :: [Address] -> Limits -> DatabaseReaderT m [Unspent]
getAddressesUnspents as :: [Address]
as limits :: Limits
limits = ReaderT DatabaseReader m DatabaseReader
forall r (m :: * -> *). MonadReader r m => m r
ask ReaderT DatabaseReader m DatabaseReader
-> (DatabaseReader -> DatabaseReaderT m [Unspent])
-> DatabaseReaderT m [Unspent]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [Address]
-> Limits -> DatabaseReader -> DatabaseReaderT m [Unspent]
forall (m :: * -> *).
MonadIO m =>
[Address] -> Limits -> DatabaseReader -> m [Unspent]
getAddressesUnspentsDB [Address]
as Limits
limits
    getAddressUnspents :: Address -> Limits -> DatabaseReaderT m [Unspent]
getAddressUnspents a :: Address
a limits :: Limits
limits = ReaderT DatabaseReader m DatabaseReader
forall r (m :: * -> *). MonadReader r m => m r
ask ReaderT DatabaseReader m DatabaseReader
-> (DatabaseReader -> DatabaseReaderT m [Unspent])
-> DatabaseReaderT m [Unspent]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Address -> Limits -> DatabaseReader -> DatabaseReaderT m [Unspent]
forall (m :: * -> *).
MonadIO m =>
Address -> Limits -> DatabaseReader -> m [Unspent]
getAddressUnspentsDB Address
a Limits
limits
    getAddressTxs :: Address -> Limits -> DatabaseReaderT m [TxRef]
getAddressTxs a :: Address
a limits :: Limits
limits = ReaderT DatabaseReader m DatabaseReader
forall r (m :: * -> *). MonadReader r m => m r
ask ReaderT DatabaseReader m DatabaseReader
-> (DatabaseReader -> DatabaseReaderT m [TxRef])
-> DatabaseReaderT m [TxRef]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Address -> Limits -> DatabaseReader -> DatabaseReaderT m [TxRef]
forall (m :: * -> *).
MonadIO m =>
Address -> Limits -> DatabaseReader -> m [TxRef]
getAddressTxsDB Address
a Limits
limits
    getMaxGap :: DatabaseReaderT m Word32
getMaxGap = (DatabaseReader -> Word32) -> DatabaseReaderT m Word32
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks DatabaseReader -> Word32
databaseMaxGap
    getInitialGap :: DatabaseReaderT m Word32
getInitialGap = (DatabaseReader -> Word32) -> DatabaseReaderT m Word32
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks DatabaseReader -> Word32
databaseInitialGap
    getNumTxData :: Word64 -> DatabaseReaderT m [TxData]
getNumTxData t :: Word64
t = ReaderT DatabaseReader m DatabaseReader
forall r (m :: * -> *). MonadReader r m => m r
ask ReaderT DatabaseReader m DatabaseReader
-> (DatabaseReader -> DatabaseReaderT m [TxData])
-> DatabaseReaderT m [TxData]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Word64 -> DatabaseReader -> DatabaseReaderT m [TxData]
forall (m :: * -> *).
MonadIO m =>
Word64 -> DatabaseReader -> m [TxData]
getNumTxDataDB Word64
t