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

import           Conduit                      (ConduitT, dropWhileC, 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                    (sortOn)
import           Data.Maybe                   (fromMaybe)
import           Data.Ord                     (Down (..))
import           Data.Serialize               (encode)
import           Data.Word                    (Word32, Word64)
import           Database.RocksDB             (ColumnFamily, Config (..),
                                               DB (..), Iterator, 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 qualified System.Metrics               as Metrics
import           System.Metrics.Counter       (Counter)
import qualified System.Metrics.Counter       as Counter
import           UnliftIO                     (MonadIO, MonadUnliftIO, liftIO)

type DatabaseReaderT = ReaderT DatabaseReader

data DatabaseStats =
    DatabaseStats
        { DatabaseStats -> Counter
databaseBlockCount   :: !Counter
        , DatabaseStats -> Counter
databaseTxCount      :: !Counter
        , DatabaseStats -> Counter
databaseBalanceCount :: !Counter
        , DatabaseStats -> Counter
databaseUnspentCount :: !Counter
        , DatabaseStats -> Counter
databaseTxRefCount   :: !Counter
        , DatabaseStats -> Counter
databaseDerivations  :: !Counter
        }

data DatabaseReader =
    DatabaseReader
        { DatabaseReader -> DB
databaseHandle     :: !DB
        , DatabaseReader -> Word32
databaseMaxGap     :: !Word32
        , DatabaseReader -> Word32
databaseInitialGap :: !Word32
        , DatabaseReader -> Network
databaseNetwork    :: !Network
        , DatabaseReader -> Maybe DatabaseStats
databaseStats      :: !(Maybe DatabaseStats)
        }

createDatabaseStats :: MonadIO m => Metrics.Store -> m DatabaseStats
createDatabaseStats :: Store -> m DatabaseStats
createDatabaseStats Store
s = IO DatabaseStats -> m DatabaseStats
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO DatabaseStats -> m DatabaseStats)
-> IO DatabaseStats -> m DatabaseStats
forall a b. (a -> b) -> a -> b
$ do
    Counter
databaseBlockCount          <- Text -> Store -> IO Counter
Metrics.createCounter Text
"database.blocks"      Store
s
    Counter
databaseTxCount             <- Text -> Store -> IO Counter
Metrics.createCounter Text
"database.txs"         Store
s
    Counter
databaseBalanceCount        <- Text -> Store -> IO Counter
Metrics.createCounter Text
"database.balances"    Store
s
    Counter
databaseUnspentCount        <- Text -> Store -> IO Counter
Metrics.createCounter Text
"database.unspents"    Store
s
    Counter
databaseTxRefCount          <- Text -> Store -> IO Counter
Metrics.createCounter Text
"database.txrefs"      Store
s
    Counter
databaseDerivations         <- Text -> Store -> IO Counter
Metrics.createCounter Text
"database.derivations" Store
s
    DatabaseStats -> IO DatabaseStats
forall (m :: * -> *) a. Monad m => a -> m a
return DatabaseStats :: Counter
-> Counter
-> Counter
-> Counter
-> Counter
-> Counter
-> DatabaseStats
DatabaseStats{Counter
databaseDerivations :: Counter
databaseTxRefCount :: Counter
databaseUnspentCount :: Counter
databaseBalanceCount :: Counter
databaseTxCount :: Counter
databaseBlockCount :: Counter
databaseDerivations :: Counter
databaseTxRefCount :: Counter
databaseUnspentCount :: Counter
databaseBalanceCount :: Counter
databaseTxCount :: Counter
databaseBlockCount :: Counter
..}

incrementCounter :: MonadIO m
                 => (DatabaseStats -> Counter)
                 -> Int
                 -> ReaderT DatabaseReader m ()
incrementCounter :: (DatabaseStats -> Counter) -> Int -> ReaderT DatabaseReader m ()
incrementCounter DatabaseStats -> Counter
f Int
i = do
    Maybe DatabaseStats
stats <- (DatabaseReader -> Maybe DatabaseStats)
-> ReaderT DatabaseReader m (Maybe DatabaseStats)
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks DatabaseReader -> Maybe DatabaseStats
databaseStats
    case Maybe DatabaseStats
stats of
        Just DatabaseStats
s  -> IO () -> ReaderT DatabaseReader m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ReaderT DatabaseReader m ())
-> IO () -> ReaderT DatabaseReader m ()
forall a b. (a -> b) -> a -> b
$ Counter -> Int64 -> IO ()
Counter.add (DatabaseStats -> Counter
f DatabaseStats
s) (Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i)
        Maybe DatabaseStats
Nothing -> () -> ReaderT DatabaseReader m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

dataVersion :: Word32
dataVersion :: Word32
dataVersion = Word32
17

withDatabaseReader :: MonadUnliftIO m
                   => Network
                   -> Word32
                   -> Word32
                   -> FilePath
                   -> Maybe DatabaseStats
                   -> DatabaseReaderT m a
                   -> m a
withDatabaseReader :: Network
-> Word32
-> Word32
-> FilePath
-> Maybe DatabaseStats
-> DatabaseReaderT m a
-> m a
withDatabaseReader Network
net Word32
igap Word32
gap FilePath
dir Maybe DatabaseStats
stats 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 -> do
    let bdb :: DatabaseReader
bdb =
            DatabaseReader :: DB
-> Word32
-> Word32
-> Network
-> Maybe DatabaseStats
-> DatabaseReader
DatabaseReader
                { databaseHandle :: DB
databaseHandle = DB
db
                , databaseMaxGap :: Word32
databaseMaxGap = Word32
gap
                , databaseNetwork :: Network
databaseNetwork = Network
net
                , databaseInitialGap :: Word32
databaseInitialGap = Word32
igap
                , databaseStats :: Maybe DatabaseStats
databaseStats = Maybe DatabaseStats
stats
                }
    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 (-Int
1)}

columnFamilyConfig :: [(String, Config)]
columnFamilyConfig :: [(FilePath, Config)]
columnFamilyConfig =
          [ (FilePath
"addr-tx",     Config
forall a. Default a => a
def{prefixLength :: Maybe Int
prefixLength = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
22, bloomFilter :: Bool
bloomFilter = Bool
True})
          , (FilePath
"addr-out",    Config
forall a. Default a => a
def{prefixLength :: Maybe Int
prefixLength = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
22, bloomFilter :: Bool
bloomFilter = Bool
True})
          , (FilePath
"tx",          Config
forall a. Default a => a
def{prefixLength :: Maybe Int
prefixLength = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
33, bloomFilter :: Bool
bloomFilter = Bool
True})
          , (FilePath
"spender",     Config
forall a. Default a => a
def{prefixLength :: Maybe Int
prefixLength = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
33, bloomFilter :: Bool
bloomFilter = Bool
True})
          , (FilePath
"unspent",     Config
forall a. Default a => a
def{prefixLength :: Maybe Int
prefixLength = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
37, bloomFilter :: Bool
bloomFilter = Bool
True})
          , (FilePath
"block",       Config
forall a. Default a => a
def{prefixLength :: Maybe Int
prefixLength = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
33, bloomFilter :: Bool
bloomFilter = Bool
True})
          , (FilePath
"height",      Config
forall a. Default a => a
def{prefixLength :: Maybe Int
prefixLength = Maybe Int
forall a. Maybe a
Nothing, bloomFilter :: Bool
bloomFilter = Bool
True})
          , (FilePath
"balance",     Config
forall a. Default a => a
def{prefixLength :: Maybe Int
prefixLength = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
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 -> [ColumnFamily]
columnFamilies DB
db [ColumnFamily] -> Int -> ColumnFamily
forall a. [a] -> Int -> a
!! Int
1

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

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

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

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

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

balanceCF :: DB -> ColumnFamily
balanceCF :: DB -> ColumnFamily
balanceCF DB
db = DB -> [ColumnFamily]
columnFamilies DB
db [ColumnFamily] -> Int -> ColumnFamily
forall a. [a] -> Int -> a
!! Int
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 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 FilePath
"Incorrect RocksDB database version"
            Maybe Word32
Nothing -> DB -> ExceptT FilePath m ()
forall (m :: * -> *). MonadIO m => DB -> m ()
setInitRocksDB DB
db
    case Either FilePath ()
e of
        Left 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 -> 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

getBestDB :: MonadIO m
          => DatabaseReaderT m (Maybe BlockHash)
getBestDB :: DatabaseReaderT m (Maybe BlockHash)
getBestDB =
    (DatabaseReader -> DB) -> ReaderT DatabaseReader m DB
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks DatabaseReader -> DB
databaseHandle ReaderT DatabaseReader m DB
-> (DB -> DatabaseReaderT m (Maybe BlockHash))
-> DatabaseReaderT m (Maybe BlockHash)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (DB -> BestKey -> DatabaseReaderT m (Maybe BlockHash)
forall (m :: * -> *) key value.
(MonadIO m, KeyValue key value, Serialize key, Serialize value) =>
DB -> key -> m (Maybe value)
`retrieve` BestKey
BestKey)

getBlocksAtHeightDB :: MonadIO m
                    => BlockHeight
                    -> DatabaseReaderT m [BlockHash]
getBlocksAtHeightDB :: Word32 -> DatabaseReaderT m [BlockHash]
getBlocksAtHeightDB Word32
h = do
    DB
db <- (DatabaseReader -> DB) -> ReaderT DatabaseReader m DB
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks DatabaseReader -> DB
databaseHandle
    DB
-> ColumnFamily
-> HeightKey
-> ReaderT DatabaseReader 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) ReaderT DatabaseReader m (Maybe [BlockHash])
-> (Maybe [BlockHash] -> DatabaseReaderT m [BlockHash])
-> DatabaseReaderT m [BlockHash]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Maybe [BlockHash]
Nothing -> [BlockHash] -> DatabaseReaderT m [BlockHash]
forall (m :: * -> *) a. Monad m => a -> m a
return []
        Just [BlockHash]
ls -> Int -> ReaderT DatabaseReader m ()
forall (m :: * -> *). StoreReadBase m => Int -> m ()
countBlocks ([BlockHash] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [BlockHash]
ls) ReaderT DatabaseReader m ()
-> DatabaseReaderT m [BlockHash] -> DatabaseReaderT m [BlockHash]
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [BlockHash] -> DatabaseReaderT m [BlockHash]
forall (m :: * -> *) a. Monad m => a -> m a
return [BlockHash]
ls

getDatabaseReader :: MonadIO m
                  => BlockHash
                  -> DatabaseReaderT m (Maybe BlockData)
getDatabaseReader :: BlockHash -> DatabaseReaderT m (Maybe BlockData)
getDatabaseReader BlockHash
h = do
    DB
db <- (DatabaseReader -> DB) -> ReaderT DatabaseReader m DB
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks DatabaseReader -> DB
databaseHandle
    DB
-> ColumnFamily -> BlockKey -> DatabaseReaderT 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) DatabaseReaderT m (Maybe BlockData)
-> (Maybe BlockData -> DatabaseReaderT m (Maybe BlockData))
-> DatabaseReaderT m (Maybe BlockData)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Maybe BlockData
Nothing -> Maybe BlockData -> DatabaseReaderT m (Maybe BlockData)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe BlockData
forall a. Maybe a
Nothing
        Just BlockData
b  -> Int -> ReaderT DatabaseReader m ()
forall (m :: * -> *). StoreReadBase m => Int -> m ()
countBlocks Int
1 ReaderT DatabaseReader m ()
-> DatabaseReaderT m (Maybe BlockData)
-> DatabaseReaderT m (Maybe BlockData)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Maybe BlockData -> DatabaseReaderT m (Maybe BlockData)
forall (m :: * -> *) a. Monad m => a -> m a
return (BlockData -> Maybe BlockData
forall a. a -> Maybe a
Just BlockData
b)

getTxDataDB :: MonadIO m
            => TxHash -> DatabaseReaderT m (Maybe TxData)
getTxDataDB :: TxHash -> DatabaseReaderT m (Maybe TxData)
getTxDataDB TxHash
th = do
    DB
db <- (DatabaseReader -> DB) -> ReaderT DatabaseReader m DB
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks DatabaseReader -> DB
databaseHandle
    DB -> ColumnFamily -> TxKey -> DatabaseReaderT 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) DatabaseReaderT m (Maybe TxData)
-> (Maybe TxData -> DatabaseReaderT m (Maybe TxData))
-> DatabaseReaderT m (Maybe TxData)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Maybe TxData
Nothing -> Maybe TxData -> DatabaseReaderT m (Maybe TxData)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe TxData
forall a. Maybe a
Nothing
        Just TxData
t  -> Int -> ReaderT DatabaseReader m ()
forall (m :: * -> *). StoreReadBase m => Int -> m ()
countTxs Int
1 ReaderT DatabaseReader m ()
-> DatabaseReaderT m (Maybe TxData)
-> DatabaseReaderT m (Maybe TxData)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Maybe TxData -> DatabaseReaderT m (Maybe TxData)
forall (m :: * -> *) a. Monad m => a -> m a
return (TxData -> Maybe TxData
forall a. a -> Maybe a
Just TxData
t)

getNumTxDataDB :: MonadIO m
               => Word64
               -> DatabaseReaderT m [TxData]
getNumTxDataDB :: Word64 -> DatabaseReaderT m [TxData]
getNumTxDataDB Word64
i = do
    DB
db <- (DatabaseReader -> DB) -> ReaderT DatabaseReader m DB
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks DatabaseReader -> DB
databaseHandle
    let ((Word32, Word16)
sk, Word8
w) = Word64 -> ((Word32, Word16), Word8)
decodeTxKey Word64
i
    [(TxKey, TxData)]
ls <- IO [(TxKey, TxData)] -> ReaderT DatabaseReader m [(TxKey, TxData)]
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [(TxKey, TxData)]
 -> ReaderT DatabaseReader m [(TxKey, TxData)])
-> IO [(TxKey, TxData)]
-> ReaderT DatabaseReader 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 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 Int
6 ByteString
bs)
                  w' :: Word8
w' = Word8
b Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0xf8
              in Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
w'
        txs :: [TxData]
txs = (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
    Int -> ReaderT DatabaseReader m ()
forall (m :: * -> *). StoreReadBase m => Int -> m ()
countTxs ([TxData] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [TxData]
txs)
    [TxData] -> DatabaseReaderT m [TxData]
forall (m :: * -> *) a. Monad m => a -> m a
return [TxData]
txs

getSpenderDB :: MonadIO m
             => OutPoint
             -> DatabaseReaderT m (Maybe Spender)
getSpenderDB :: OutPoint -> DatabaseReaderT m (Maybe Spender)
getSpenderDB OutPoint
op = do
    DB
db <- (DatabaseReader -> DB) -> ReaderT DatabaseReader m DB
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks DatabaseReader -> DB
databaseHandle
    DB
-> ColumnFamily -> SpenderKey -> DatabaseReaderT 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 -> DatabaseReaderT m (Maybe Spender))
-> SpenderKey -> DatabaseReaderT m (Maybe Spender)
forall a b. (a -> b) -> a -> b
$ OutPoint -> SpenderKey
SpenderKey OutPoint
op

getBalanceDB :: MonadIO m
             => Address
             -> DatabaseReaderT m (Maybe Balance)
getBalanceDB :: Address -> DatabaseReaderT m (Maybe Balance)
getBalanceDB Address
a = do
    DB
db <- (DatabaseReader -> DB) -> ReaderT DatabaseReader m DB
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks DatabaseReader -> DB
databaseHandle
    (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)
-> ReaderT DatabaseReader m (Maybe BalVal)
-> DatabaseReaderT m (Maybe Balance)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DB
-> ColumnFamily
-> BalKey
-> ReaderT DatabaseReader 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) DatabaseReaderT m (Maybe Balance)
-> (Maybe Balance -> DatabaseReaderT m (Maybe Balance))
-> DatabaseReaderT m (Maybe Balance)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Maybe Balance
Nothing -> Maybe Balance -> DatabaseReaderT m (Maybe Balance)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Balance
forall a. Maybe a
Nothing
        Just Balance
b  -> Int -> ReaderT DatabaseReader m ()
forall (m :: * -> *). StoreReadBase m => Int -> m ()
countBalances Int
1 ReaderT DatabaseReader m ()
-> DatabaseReaderT m (Maybe Balance)
-> DatabaseReaderT m (Maybe Balance)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Maybe Balance -> DatabaseReaderT m (Maybe Balance)
forall (m :: * -> *) a. Monad m => a -> m a
return (Balance -> Maybe Balance
forall a. a -> Maybe a
Just Balance
b)

getMempoolDB :: MonadIO m
             => DatabaseReaderT m [(UnixTime, TxHash)]
getMempoolDB :: DatabaseReaderT m [(Word64, TxHash)]
getMempoolDB = do
    DB
db <- (DatabaseReader -> DB) -> ReaderT DatabaseReader m DB
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks DatabaseReader -> DB
databaseHandle
    [(Word64, TxHash)]
-> Maybe [(Word64, TxHash)] -> [(Word64, TxHash)]
forall a. a -> Maybe a -> a
fromMaybe [] (Maybe [(Word64, TxHash)] -> [(Word64, TxHash)])
-> ReaderT DatabaseReader m (Maybe [(Word64, TxHash)])
-> DatabaseReaderT m [(Word64, TxHash)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DB -> MemKey -> ReaderT DatabaseReader 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 :: MonadUnliftIO m
                  => [Address]
                  -> Limits
                  -> DatabaseReaderT m [TxRef]
getAddressesTxsDB :: [Address] -> Limits -> DatabaseReaderT m [TxRef]
getAddressesTxsDB [Address]
addrs Limits
limits = do
    [TxRef]
txs <- Limits -> [TxRef] -> [TxRef]
forall a. Limits -> [a] -> [a]
applyLimits Limits
limits ([TxRef] -> [TxRef])
-> ([[TxRef]] -> [TxRef]) -> [[TxRef]] -> [TxRef]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TxRef -> Down TxRef) -> [TxRef] -> [TxRef]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn TxRef -> Down TxRef
forall a. a -> Down a
Down ([TxRef] -> [TxRef])
-> ([[TxRef]] -> [TxRef]) -> [[TxRef]] -> [TxRef]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[TxRef]] -> [TxRef]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[TxRef]] -> [TxRef])
-> ReaderT DatabaseReader m [[TxRef]] -> DatabaseReaderT m [TxRef]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Address -> DatabaseReaderT m [TxRef])
-> [Address] -> ReaderT DatabaseReader m [[TxRef]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Address -> DatabaseReaderT m [TxRef]
forall (m :: * -> *).
MonadUnliftIO m =>
Address -> DatabaseReaderT m [TxRef]
f [Address]
addrs
    Int -> ReaderT DatabaseReader m ()
forall (m :: * -> *). StoreReadExtra m => Int -> m ()
countTxRefs ([TxRef] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [TxRef]
txs)
    [TxRef] -> DatabaseReaderT m [TxRef]
forall (m :: * -> *) a. Monad m => a -> m a
return [TxRef]
txs
  where
    l :: Limits
l = Limits -> Limits
deOffset Limits
limits
    f :: Address -> DatabaseReaderT m [TxRef]
f Address
a = do
        DB
db <- (DatabaseReader -> DB) -> DatabaseReaderT m DB
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks DatabaseReader -> DB
databaseHandle
        DB
-> ColumnFamily
-> (Iterator -> DatabaseReaderT m [TxRef])
-> DatabaseReaderT m [TxRef]
forall (m :: * -> *) a.
MonadUnliftIO m =>
DB -> ColumnFamily -> (Iterator -> m a) -> m a
withIterCF DB
db (DB -> ColumnFamily
addrTxCF DB
db) ((Iterator -> DatabaseReaderT m [TxRef])
 -> DatabaseReaderT m [TxRef])
-> (Iterator -> DatabaseReaderT m [TxRef])
-> DatabaseReaderT m [TxRef]
forall a b. (a -> b) -> a -> b
$ \Iterator
it ->
            ConduitT () Void (DatabaseReaderT m) [TxRef]
-> DatabaseReaderT m [TxRef]
forall (m :: * -> *) r. Monad m => ConduitT () Void m r -> m r
runConduit (ConduitT () Void (DatabaseReaderT m) [TxRef]
 -> DatabaseReaderT m [TxRef])
-> ConduitT () Void (DatabaseReaderT m) [TxRef]
-> DatabaseReaderT m [TxRef]
forall a b. (a -> b) -> a -> b
$
            Address
-> Maybe Start
-> Iterator
-> ConduitT () TxRef (DatabaseReaderT m) ()
forall (m :: * -> *) i.
MonadUnliftIO m =>
Address
-> Maybe Start
-> Iterator
-> ConduitT i TxRef (DatabaseReaderT m) ()
addressConduit Address
a (Limits -> Maybe Start
start Limits
l) Iterator
it ConduitT () TxRef (DatabaseReaderT m) ()
-> ConduitM TxRef Void (DatabaseReaderT m) [TxRef]
-> ConduitT () Void (DatabaseReaderT m) [TxRef]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.|
            Word32 -> ConduitT TxRef TxRef (DatabaseReaderT m) ()
forall (m :: * -> *) i. Monad m => Word32 -> ConduitT i i m ()
applyLimitC (Limits -> Word32
limit Limits
l) ConduitT TxRef TxRef (DatabaseReaderT m) ()
-> ConduitM TxRef Void (DatabaseReaderT m) [TxRef]
-> ConduitM TxRef Void (DatabaseReaderT m) [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 (DatabaseReaderT m) [TxRef]
forall (m :: * -> *) a o. Monad m => ConduitT a o m [a]
sinkList

addressConduit :: MonadUnliftIO m
               => Address
               -> Maybe Start
               -> Iterator
               -> ConduitT i TxRef (DatabaseReaderT m) ()
addressConduit :: Address
-> Maybe Start
-> Iterator
-> ConduitT i TxRef (DatabaseReaderT m) ()
addressConduit Address
a Maybe Start
s Iterator
it  =
    ConduitT i (AddrTxKey, ()) (DatabaseReaderT m) ()
forall i. ConduitT i (AddrTxKey, ()) (DatabaseReaderT m) ()
x ConduitT i (AddrTxKey, ()) (DatabaseReaderT m) ()
-> ConduitM (AddrTxKey, ()) TxRef (DatabaseReaderT m) ()
-> ConduitT i TxRef (DatabaseReaderT m) ()
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.| ((AddrTxKey, ()) -> TxRef)
-> ConduitM (AddrTxKey, ()) TxRef (DatabaseReaderT m) ()
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)
  where
    f :: AddrTxKey -> () -> TxRef
f (AddrTxKey Address
_ TxRef
t) () = TxRef
t
    f AddrTxKey
_ ()
_                = TxRef
forall a. HasCallStack => a
undefined
    x :: ConduitT i (AddrTxKey, ()) (DatabaseReaderT m) ()
x = case Maybe Start
s of
        Maybe Start
Nothing ->
            Iterator
-> AddrTxKey -> ConduitT i (AddrTxKey, ()) (DatabaseReaderT 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 Word32
bh) ->
            Iterator
-> AddrTxKey
-> AddrTxKey
-> ConduitT i (AddrTxKey, ()) (DatabaseReaderT 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))
        Just (AtTx TxHash
txh) ->
            ReaderT DatabaseReader m (Maybe TxData)
-> ConduitT i (AddrTxKey, ()) (DatabaseReaderT m) (Maybe TxData)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (TxHash -> ReaderT DatabaseReader m (Maybe TxData)
forall (m :: * -> *).
MonadIO m =>
TxHash -> DatabaseReaderT m (Maybe TxData)
getTxDataDB TxHash
txh) ConduitT i (AddrTxKey, ()) (DatabaseReaderT m) (Maybe TxData)
-> (Maybe TxData
    -> ConduitT i (AddrTxKey, ()) (DatabaseReaderT m) ())
-> ConduitT i (AddrTxKey, ()) (DatabaseReaderT 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, ()) (DatabaseReaderT 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)
                Just TxData {txDataBlock :: TxData -> BlockRef
txDataBlock = MemRef{}} ->
                    let cond :: AddrTxKey -> Bool
cond (AddrTxKey Address
_a (TxRef MemRef{} TxHash
th)) =
                            TxHash
th TxHash -> TxHash -> Bool
forall a. Eq a => a -> a -> Bool
/= TxHash
txh
                        cond (AddrTxKey Address
_a (TxRef BlockRef{} TxHash
_th)) =
                            Bool
False
                    in Iterator
-> AddrTxKey -> ConduitT i (AddrTxKey, ()) (DatabaseReaderT 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) ConduitT i (AddrTxKey, ()) (DatabaseReaderT m) ()
-> ConduitM (AddrTxKey, ()) (AddrTxKey, ()) (DatabaseReaderT m) ()
-> ConduitT i (AddrTxKey, ()) (DatabaseReaderT m) ()
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.|
                       (((AddrTxKey, ()) -> Bool)
-> ConduitM (AddrTxKey, ()) (AddrTxKey, ()) (DatabaseReaderT m) ()
forall (m :: * -> *) a o.
Monad m =>
(a -> Bool) -> ConduitT a o m ()
dropWhileC (AddrTxKey -> Bool
cond (AddrTxKey -> Bool)
-> ((AddrTxKey, ()) -> AddrTxKey) -> (AddrTxKey, ()) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (AddrTxKey, ()) -> AddrTxKey
forall a b. (a, b) -> a
fst) ConduitM (AddrTxKey, ()) (AddrTxKey, ()) (DatabaseReaderT m) ()
-> ConduitM (AddrTxKey, ()) (AddrTxKey, ()) (DatabaseReaderT m) ()
-> ConduitM (AddrTxKey, ()) (AddrTxKey, ()) (DatabaseReaderT m) ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ((AddrTxKey, ()) -> (AddrTxKey, ()))
-> ConduitM (AddrTxKey, ()) (AddrTxKey, ()) (DatabaseReaderT m) ()
forall (m :: * -> *) a b. Monad m => (a -> b) -> ConduitT a b m ()
mapC (AddrTxKey, ()) -> (AddrTxKey, ())
forall a. a -> a
id)
                Maybe TxData
Nothing -> () -> ConduitT i (AddrTxKey, ()) (DatabaseReaderT m) ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

getAddressTxsDB :: MonadUnliftIO m
                => Address
                -> Limits
                -> DatabaseReaderT m [TxRef]
getAddressTxsDB :: Address -> Limits -> DatabaseReaderT m [TxRef]
getAddressTxsDB Address
a Limits
limits = do
    DB
db <- (DatabaseReader -> DB) -> ReaderT DatabaseReader m DB
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks DatabaseReader -> DB
databaseHandle
    [TxRef]
txs <- DB
-> ColumnFamily
-> (Iterator -> DatabaseReaderT m [TxRef])
-> DatabaseReaderT m [TxRef]
forall (m :: * -> *) a.
MonadUnliftIO m =>
DB -> ColumnFamily -> (Iterator -> m a) -> m a
withIterCF DB
db (DB -> ColumnFamily
addrTxCF DB
db) ((Iterator -> DatabaseReaderT m [TxRef])
 -> DatabaseReaderT m [TxRef])
-> (Iterator -> DatabaseReaderT m [TxRef])
-> DatabaseReaderT m [TxRef]
forall a b. (a -> b) -> a -> b
$ \Iterator
it ->
        ConduitT () Void (DatabaseReaderT m) [TxRef]
-> DatabaseReaderT m [TxRef]
forall (m :: * -> *) r. Monad m => ConduitT () Void m r -> m r
runConduit (ConduitT () Void (DatabaseReaderT m) [TxRef]
 -> DatabaseReaderT m [TxRef])
-> ConduitT () Void (DatabaseReaderT m) [TxRef]
-> DatabaseReaderT m [TxRef]
forall a b. (a -> b) -> a -> b
$
        Address
-> Maybe Start
-> Iterator
-> ConduitT () TxRef (DatabaseReaderT m) ()
forall (m :: * -> *) i.
MonadUnliftIO m =>
Address
-> Maybe Start
-> Iterator
-> ConduitT i TxRef (DatabaseReaderT m) ()
addressConduit Address
a (Limits -> Maybe Start
start Limits
limits) Iterator
it ConduitT () TxRef (DatabaseReaderT m) ()
-> ConduitM TxRef Void (DatabaseReaderT m) [TxRef]
-> ConduitT () Void (DatabaseReaderT m) [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 TxRef TxRef (DatabaseReaderT m) ()
forall (m :: * -> *) i. Monad m => Limits -> ConduitT i i m ()
applyLimitsC Limits
limits ConduitT TxRef TxRef (DatabaseReaderT m) ()
-> ConduitM TxRef Void (DatabaseReaderT m) [TxRef]
-> ConduitM TxRef Void (DatabaseReaderT m) [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 (DatabaseReaderT m) [TxRef]
forall (m :: * -> *) a o. Monad m => ConduitT a o m [a]
sinkList
    Int -> ReaderT DatabaseReader m ()
forall (m :: * -> *). StoreReadExtra m => Int -> m ()
countTxRefs ([TxRef] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [TxRef]
txs)
    [TxRef] -> DatabaseReaderT m [TxRef]
forall (m :: * -> *) a. Monad m => a -> m a
return [TxRef]
txs

getUnspentDB :: MonadIO m
             => OutPoint
             -> DatabaseReaderT m (Maybe Unspent)
getUnspentDB :: OutPoint -> DatabaseReaderT m (Maybe Unspent)
getUnspentDB OutPoint
p = do
    DB
db <- (DatabaseReader -> DB) -> ReaderT DatabaseReader m DB
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks DatabaseReader -> DB
databaseHandle
    (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)
-> ReaderT DatabaseReader m (Maybe UnspentVal)
-> DatabaseReaderT m (Maybe Unspent)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DB
-> ColumnFamily
-> UnspentKey
-> ReaderT DatabaseReader 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) DatabaseReaderT m (Maybe Unspent)
-> (Maybe Unspent -> DatabaseReaderT m (Maybe Unspent))
-> DatabaseReaderT m (Maybe Unspent)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Maybe Unspent
Nothing -> Maybe Unspent -> DatabaseReaderT m (Maybe Unspent)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Unspent
forall a. Maybe a
Nothing
        Just Unspent
u  -> Int -> ReaderT DatabaseReader m ()
forall (m :: * -> *). StoreReadBase m => Int -> m ()
countUnspents Int
1 ReaderT DatabaseReader m ()
-> DatabaseReaderT m (Maybe Unspent)
-> DatabaseReaderT m (Maybe Unspent)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Maybe Unspent -> DatabaseReaderT m (Maybe Unspent)
forall (m :: * -> *) a. Monad m => a -> m a
return (Unspent -> Maybe Unspent
forall a. a -> Maybe a
Just Unspent
u)

getAddressesUnspentsDB :: MonadUnliftIO m
                       => [Address]
                       -> Limits
                       -> DatabaseReaderT m [Unspent]
getAddressesUnspentsDB :: [Address] -> Limits -> DatabaseReaderT m [Unspent]
getAddressesUnspentsDB [Address]
addrs Limits
limits = do
    [Unspent]
us <- Limits -> [Unspent] -> [Unspent]
forall a. Limits -> [a] -> [a]
applyLimits Limits
limits ([Unspent] -> [Unspent])
-> ([[Unspent]] -> [Unspent]) -> [[Unspent]] -> [Unspent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Unspent -> Down Unspent) -> [Unspent] -> [Unspent]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn Unspent -> Down Unspent
forall a. a -> Down a
Down ([Unspent] -> [Unspent])
-> ([[Unspent]] -> [Unspent]) -> [[Unspent]] -> [Unspent]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Unspent]] -> [Unspent]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Unspent]] -> [Unspent])
-> ReaderT DatabaseReader m [[Unspent]]
-> DatabaseReaderT m [Unspent]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Address -> DatabaseReaderT m [Unspent])
-> [Address] -> ReaderT DatabaseReader m [[Unspent]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Address -> DatabaseReaderT m [Unspent]
forall (m :: * -> *).
MonadUnliftIO m =>
Address -> DatabaseReaderT m [Unspent]
f [Address]
addrs
    Int -> ReaderT DatabaseReader m ()
forall (m :: * -> *). StoreReadBase m => Int -> m ()
countUnspents ([Unspent] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Unspent]
us)
    [Unspent] -> DatabaseReaderT m [Unspent]
forall (m :: * -> *) a. Monad m => a -> m a
return [Unspent]
us
  where
    l :: Limits
l = Limits -> Limits
deOffset Limits
limits
    f :: Address -> DatabaseReaderT m [Unspent]
f Address
a = do
        DB
db <- (DatabaseReader -> DB) -> DatabaseReaderT m DB
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks DatabaseReader -> DB
databaseHandle
        DB
-> ColumnFamily
-> (Iterator -> DatabaseReaderT m [Unspent])
-> DatabaseReaderT m [Unspent]
forall (m :: * -> *) a.
MonadUnliftIO m =>
DB -> ColumnFamily -> (Iterator -> m a) -> m a
withIterCF DB
db (DB -> ColumnFamily
addrOutCF DB
db) ((Iterator -> DatabaseReaderT m [Unspent])
 -> DatabaseReaderT m [Unspent])
-> (Iterator -> DatabaseReaderT m [Unspent])
-> DatabaseReaderT m [Unspent]
forall a b. (a -> b) -> a -> b
$ \Iterator
it ->
            ConduitT () Void (DatabaseReaderT m) [Unspent]
-> DatabaseReaderT m [Unspent]
forall (m :: * -> *) r. Monad m => ConduitT () Void m r -> m r
runConduit (ConduitT () Void (DatabaseReaderT m) [Unspent]
 -> DatabaseReaderT m [Unspent])
-> ConduitT () Void (DatabaseReaderT m) [Unspent]
-> DatabaseReaderT m [Unspent]
forall a b. (a -> b) -> a -> b
$
            Address
-> Maybe Start
-> Iterator
-> ConduitT () Unspent (DatabaseReaderT m) ()
forall (m :: * -> *) i.
MonadUnliftIO m =>
Address
-> Maybe Start
-> Iterator
-> ConduitT i Unspent (DatabaseReaderT m) ()
unspentConduit Address
a (Limits -> Maybe Start
start Limits
l) Iterator
it ConduitT () Unspent (DatabaseReaderT m) ()
-> ConduitM Unspent Void (DatabaseReaderT m) [Unspent]
-> ConduitT () Void (DatabaseReaderT m) [Unspent]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.|
            Word32 -> ConduitT Unspent Unspent (DatabaseReaderT m) ()
forall (m :: * -> *) i. Monad m => Word32 -> ConduitT i i m ()
applyLimitC (Limits -> Word32
limit Limits
l) ConduitT Unspent Unspent (DatabaseReaderT m) ()
-> ConduitM Unspent Void (DatabaseReaderT m) [Unspent]
-> ConduitM Unspent Void (DatabaseReaderT m) [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 (DatabaseReaderT m) [Unspent]
forall (m :: * -> *) a o. Monad m => ConduitT a o m [a]
sinkList

unspentConduit :: MonadUnliftIO m
               => Address
               -> Maybe Start
               -> Iterator
               -> ConduitT i Unspent (DatabaseReaderT m) ()
unspentConduit :: Address
-> Maybe Start
-> Iterator
-> ConduitT i Unspent (DatabaseReaderT m) ()
unspentConduit Address
a Maybe Start
s Iterator
it =
    ConduitT i (AddrOutKey, OutVal) (DatabaseReaderT m) ()
forall i. ConduitT i (AddrOutKey, OutVal) (DatabaseReaderT m) ()
x ConduitT i (AddrOutKey, OutVal) (DatabaseReaderT m) ()
-> ConduitM (AddrOutKey, OutVal) Unspent (DatabaseReaderT m) ()
-> ConduitT i Unspent (DatabaseReaderT m) ()
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)
-> ConduitM (AddrOutKey, OutVal) Unspent (DatabaseReaderT m) ()
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)
  where
    x :: ConduitT i (AddrOutKey, OutVal) (DatabaseReaderT m) ()
x = case Maybe Start
s of
        Maybe Start
Nothing ->
            Iterator
-> AddrOutKey
-> ConduitT i (AddrOutKey, OutVal) (DatabaseReaderT 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 Word32
h) ->
            Iterator
-> AddrOutKey
-> AddrOutKey
-> ConduitT i (AddrOutKey, OutVal) (DatabaseReaderT 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 TxHash
txh) ->
            ReaderT DatabaseReader m (Maybe TxData)
-> ConduitT
     i (AddrOutKey, OutVal) (DatabaseReaderT m) (Maybe TxData)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (TxHash -> ReaderT DatabaseReader m (Maybe TxData)
forall (m :: * -> *).
MonadIO m =>
TxHash -> DatabaseReaderT m (Maybe TxData)
getTxDataDB TxHash
txh) ConduitT i (AddrOutKey, OutVal) (DatabaseReaderT m) (Maybe TxData)
-> (Maybe TxData
    -> ConduitT i (AddrOutKey, OutVal) (DatabaseReaderT m) ())
-> ConduitT i (AddrOutKey, OutVal) (DatabaseReaderT 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, OutVal) (DatabaseReaderT 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)
                Just TxData {txDataBlock :: TxData -> BlockRef
txDataBlock = MemRef{}} ->
                    let cond :: AddrOutKey -> Bool
cond (AddrOutKey Address
_a MemRef{} OutPoint
p) =
                            OutPoint -> TxHash
outPointHash OutPoint
p TxHash -> TxHash -> Bool
forall a. Eq a => a -> a -> Bool
/= TxHash
txh
                        cond (AddrOutKey Address
_a BlockRef{} OutPoint
_p) =
                            Bool
False
                    in Iterator
-> AddrOutKey
-> ConduitT i (AddrOutKey, OutVal) (DatabaseReaderT 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) ConduitT i (AddrOutKey, OutVal) (DatabaseReaderT m) ()
-> ConduitM
     (AddrOutKey, OutVal) (AddrOutKey, OutVal) (DatabaseReaderT m) ()
-> ConduitT i (AddrOutKey, OutVal) (DatabaseReaderT m) ()
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.|
                       (((AddrOutKey, OutVal) -> Bool)
-> ConduitM
     (AddrOutKey, OutVal) (AddrOutKey, OutVal) (DatabaseReaderT m) ()
forall (m :: * -> *) a o.
Monad m =>
(a -> Bool) -> ConduitT a o m ()
dropWhileC (AddrOutKey -> Bool
cond (AddrOutKey -> Bool)
-> ((AddrOutKey, OutVal) -> AddrOutKey)
-> (AddrOutKey, OutVal)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (AddrOutKey, OutVal) -> AddrOutKey
forall a b. (a, b) -> a
fst) ConduitM
  (AddrOutKey, OutVal) (AddrOutKey, OutVal) (DatabaseReaderT m) ()
-> ConduitM
     (AddrOutKey, OutVal) (AddrOutKey, OutVal) (DatabaseReaderT m) ()
-> ConduitM
     (AddrOutKey, OutVal) (AddrOutKey, OutVal) (DatabaseReaderT m) ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ((AddrOutKey, OutVal) -> (AddrOutKey, OutVal))
-> ConduitM
     (AddrOutKey, OutVal) (AddrOutKey, OutVal) (DatabaseReaderT m) ()
forall (m :: * -> *) a b. Monad m => (a -> b) -> ConduitT a b m ()
mapC (AddrOutKey, OutVal) -> (AddrOutKey, OutVal)
forall a. a -> a
id)
                Maybe TxData
Nothing -> () -> ConduitT i (AddrOutKey, OutVal) (DatabaseReaderT m) ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

getAddressUnspentsDB :: MonadUnliftIO m
                     => Address
                     -> Limits
                     -> DatabaseReaderT m [Unspent]
getAddressUnspentsDB :: Address -> Limits -> DatabaseReaderT m [Unspent]
getAddressUnspentsDB Address
a Limits
limits = do
    DB
db <- (DatabaseReader -> DB) -> ReaderT DatabaseReader m DB
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks DatabaseReader -> DB
databaseHandle
    [Unspent]
us <- DB
-> ColumnFamily
-> (Iterator -> DatabaseReaderT m [Unspent])
-> DatabaseReaderT m [Unspent]
forall (m :: * -> *) a.
MonadUnliftIO m =>
DB -> ColumnFamily -> (Iterator -> m a) -> m a
withIterCF DB
db (DB -> ColumnFamily
addrOutCF DB
db) ((Iterator -> DatabaseReaderT m [Unspent])
 -> DatabaseReaderT m [Unspent])
-> (Iterator -> DatabaseReaderT m [Unspent])
-> DatabaseReaderT m [Unspent]
forall a b. (a -> b) -> a -> b
$ \Iterator
it -> ConduitT () Void (ReaderT DatabaseReader m) [Unspent]
-> DatabaseReaderT m [Unspent]
forall (m :: * -> *) r. Monad m => ConduitT () Void m r -> m r
runConduit (ConduitT () Void (ReaderT DatabaseReader m) [Unspent]
 -> DatabaseReaderT m [Unspent])
-> ConduitT () Void (ReaderT DatabaseReader m) [Unspent]
-> DatabaseReaderT m [Unspent]
forall a b. (a -> b) -> a -> b
$
        Iterator
-> ConduitT () (AddrOutKey, OutVal) (ReaderT DatabaseReader m) ()
forall (m :: * -> *) value i.
(MonadIO m, KeyValue AddrOutKey value, Serialize value) =>
Iterator
-> ConduitT i (AddrOutKey, value) (ReaderT DatabaseReader m) ()
x Iterator
it ConduitT () (AddrOutKey, OutVal) (ReaderT DatabaseReader m) ()
-> ConduitM
     (AddrOutKey, OutVal) Void (ReaderT DatabaseReader m) [Unspent]
-> ConduitT () Void (ReaderT DatabaseReader m) [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)
     (ReaderT DatabaseReader m)
     ()
forall (m :: * -> *) i. Monad m => Limits -> ConduitT i i m ()
applyLimitsC Limits
limits ConduitT
  (AddrOutKey, OutVal)
  (AddrOutKey, OutVal)
  (ReaderT DatabaseReader m)
  ()
-> ConduitM
     (AddrOutKey, OutVal) Void (ReaderT DatabaseReader m) [Unspent]
-> ConduitM
     (AddrOutKey, OutVal) Void (ReaderT DatabaseReader m) [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 (ReaderT DatabaseReader m) ()
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 (ReaderT DatabaseReader m) ()
-> ConduitM Unspent Void (ReaderT DatabaseReader m) [Unspent]
-> ConduitM
     (AddrOutKey, OutVal) Void (ReaderT DatabaseReader m) [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 (ReaderT DatabaseReader m) [Unspent]
forall (m :: * -> *) a o. Monad m => ConduitT a o m [a]
sinkList
    Int -> ReaderT DatabaseReader m ()
forall (m :: * -> *). StoreReadBase m => Int -> m ()
countUnspents ([Unspent] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Unspent]
us)
    [Unspent] -> DatabaseReaderT m [Unspent]
forall (m :: * -> *) a. Monad m => a -> m a
return [Unspent]
us
  where
    x :: Iterator
-> ConduitT i (AddrOutKey, value) (ReaderT DatabaseReader m) ()
x Iterator
it = case Limits -> Maybe Start
start Limits
limits of
        Maybe Start
Nothing ->
            Iterator
-> AddrOutKey
-> ConduitT i (AddrOutKey, value) (ReaderT DatabaseReader 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 Word32
h) ->
            Iterator
-> AddrOutKey
-> AddrOutKey
-> ConduitT i (AddrOutKey, value) (ReaderT DatabaseReader 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 TxHash
txh) ->
            ReaderT DatabaseReader m (Maybe TxData)
-> ConduitT
     i (AddrOutKey, value) (ReaderT DatabaseReader m) (Maybe TxData)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (TxHash -> ReaderT DatabaseReader m (Maybe TxData)
forall (m :: * -> *).
MonadIO m =>
TxHash -> DatabaseReaderT m (Maybe TxData)
getTxDataDB TxHash
txh) ConduitT
  i (AddrOutKey, value) (ReaderT DatabaseReader m) (Maybe TxData)
-> (Maybe TxData
    -> ConduitT i (AddrOutKey, value) (ReaderT DatabaseReader m) ())
-> ConduitT i (AddrOutKey, value) (ReaderT DatabaseReader 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) (ReaderT DatabaseReader 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)
                Just TxData {txDataBlock :: TxData -> BlockRef
txDataBlock = MemRef{}} ->
                    let cond :: AddrOutKey -> Bool
cond (AddrOutKey Address
_a MemRef{} OutPoint
p) =
                            OutPoint -> TxHash
outPointHash OutPoint
p TxHash -> TxHash -> Bool
forall a. Eq a => a -> a -> Bool
/= TxHash
txh
                        cond (AddrOutKey Address
_a BlockRef{} OutPoint
_p) =
                            Bool
False
                    in Iterator
-> AddrOutKey
-> ConduitT i (AddrOutKey, value) (ReaderT DatabaseReader 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) ConduitT i (AddrOutKey, value) (ReaderT DatabaseReader m) ()
-> ConduitM
     (AddrOutKey, value)
     (AddrOutKey, value)
     (ReaderT DatabaseReader m)
     ()
-> ConduitT i (AddrOutKey, value) (ReaderT DatabaseReader m) ()
forall (m :: * -> *) a b c r.
Monad m =>
ConduitM a b m () -> ConduitM b c m r -> ConduitM a c m r
.|
                       (((AddrOutKey, value) -> Bool)
-> ConduitM
     (AddrOutKey, value)
     (AddrOutKey, value)
     (ReaderT DatabaseReader m)
     ()
forall (m :: * -> *) a o.
Monad m =>
(a -> Bool) -> ConduitT a o m ()
dropWhileC (AddrOutKey -> Bool
cond (AddrOutKey -> Bool)
-> ((AddrOutKey, value) -> AddrOutKey)
-> (AddrOutKey, value)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (AddrOutKey, value) -> AddrOutKey
forall a b. (a, b) -> a
fst) ConduitM
  (AddrOutKey, value)
  (AddrOutKey, value)
  (ReaderT DatabaseReader m)
  ()
-> ConduitM
     (AddrOutKey, value)
     (AddrOutKey, value)
     (ReaderT DatabaseReader m)
     ()
-> ConduitM
     (AddrOutKey, value)
     (AddrOutKey, value)
     (ReaderT DatabaseReader m)
     ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ((AddrOutKey, value) -> (AddrOutKey, value))
-> ConduitM
     (AddrOutKey, value)
     (AddrOutKey, value)
     (ReaderT DatabaseReader m)
     ()
forall (m :: * -> *) a b. Monad m => (a -> b) -> ConduitT a b m ()
mapC (AddrOutKey, value) -> (AddrOutKey, value)
forall a. a -> a
id)
                Maybe TxData
_ -> Iterator
-> AddrOutKey
-> ConduitT i (AddrOutKey, value) (ReaderT DatabaseReader 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 TxHash
t = TxHash -> DatabaseReaderT m (Maybe TxData)
forall (m :: * -> *).
MonadIO m =>
TxHash -> DatabaseReaderT m (Maybe TxData)
getTxDataDB TxHash
t
    getSpender :: OutPoint -> DatabaseReaderT m (Maybe Spender)
getSpender OutPoint
p = OutPoint -> DatabaseReaderT m (Maybe Spender)
forall (m :: * -> *).
MonadIO m =>
OutPoint -> DatabaseReaderT m (Maybe Spender)
getSpenderDB OutPoint
p
    getUnspent :: OutPoint -> DatabaseReaderT m (Maybe Unspent)
getUnspent OutPoint
a = OutPoint -> DatabaseReaderT m (Maybe Unspent)
forall (m :: * -> *).
MonadIO m =>
OutPoint -> DatabaseReaderT m (Maybe Unspent)
getUnspentDB OutPoint
a
    getBalance :: Address -> DatabaseReaderT m (Maybe Balance)
getBalance Address
a = Address -> DatabaseReaderT m (Maybe Balance)
forall (m :: * -> *).
MonadIO m =>
Address -> DatabaseReaderT m (Maybe Balance)
getBalanceDB Address
a
    getMempool :: DatabaseReaderT m [(Word64, TxHash)]
getMempool = DatabaseReaderT m [(Word64, TxHash)]
forall (m :: * -> *).
MonadIO m =>
DatabaseReaderT m [(Word64, TxHash)]
getMempoolDB
    getBestBlock :: DatabaseReaderT m (Maybe BlockHash)
getBestBlock = DatabaseReaderT m (Maybe BlockHash)
forall (m :: * -> *).
MonadIO m =>
DatabaseReaderT m (Maybe BlockHash)
getBestDB
    getBlocksAtHeight :: Word32 -> DatabaseReaderT m [BlockHash]
getBlocksAtHeight Word32
h = Word32 -> DatabaseReaderT m [BlockHash]
forall (m :: * -> *).
MonadIO m =>
Word32 -> DatabaseReaderT m [BlockHash]
getBlocksAtHeightDB Word32
h
    getBlock :: BlockHash -> DatabaseReaderT m (Maybe BlockData)
getBlock BlockHash
b = BlockHash -> DatabaseReaderT m (Maybe BlockData)
forall (m :: * -> *).
MonadIO m =>
BlockHash -> DatabaseReaderT m (Maybe BlockData)
getDatabaseReader BlockHash
b
    countBlocks :: Int -> DatabaseReaderT m ()
countBlocks = (DatabaseStats -> Counter) -> Int -> DatabaseReaderT m ()
forall (m :: * -> *).
MonadIO m =>
(DatabaseStats -> Counter) -> Int -> ReaderT DatabaseReader m ()
incrementCounter DatabaseStats -> Counter
databaseBlockCount
    countTxs :: Int -> DatabaseReaderT m ()
countTxs = (DatabaseStats -> Counter) -> Int -> DatabaseReaderT m ()
forall (m :: * -> *).
MonadIO m =>
(DatabaseStats -> Counter) -> Int -> ReaderT DatabaseReader m ()
incrementCounter DatabaseStats -> Counter
databaseTxCount
    countBalances :: Int -> DatabaseReaderT m ()
countBalances = (DatabaseStats -> Counter) -> Int -> DatabaseReaderT m ()
forall (m :: * -> *).
MonadIO m =>
(DatabaseStats -> Counter) -> Int -> ReaderT DatabaseReader m ()
incrementCounter DatabaseStats -> Counter
databaseBalanceCount
    countUnspents :: Int -> DatabaseReaderT m ()
countUnspents = (DatabaseStats -> Counter) -> Int -> DatabaseReaderT m ()
forall (m :: * -> *).
MonadIO m =>
(DatabaseStats -> Counter) -> Int -> ReaderT DatabaseReader m ()
incrementCounter DatabaseStats -> Counter
databaseUnspentCount

instance MonadUnliftIO m => StoreReadExtra (DatabaseReaderT m) where
    getAddressesTxs :: [Address] -> Limits -> DatabaseReaderT m [TxRef]
getAddressesTxs [Address]
as Limits
limits = [Address] -> Limits -> DatabaseReaderT m [TxRef]
forall (m :: * -> *).
MonadUnliftIO m =>
[Address] -> Limits -> DatabaseReaderT m [TxRef]
getAddressesTxsDB [Address]
as Limits
limits
    getAddressesUnspents :: [Address] -> Limits -> DatabaseReaderT m [Unspent]
getAddressesUnspents [Address]
as Limits
limits = [Address] -> Limits -> DatabaseReaderT m [Unspent]
forall (m :: * -> *).
MonadUnliftIO m =>
[Address] -> Limits -> DatabaseReaderT m [Unspent]
getAddressesUnspentsDB [Address]
as Limits
limits
    getAddressUnspents :: Address -> Limits -> DatabaseReaderT m [Unspent]
getAddressUnspents Address
a Limits
limits = Address -> Limits -> DatabaseReaderT m [Unspent]
forall (m :: * -> *).
MonadUnliftIO m =>
Address -> Limits -> DatabaseReaderT m [Unspent]
getAddressUnspentsDB Address
a Limits
limits
    getAddressTxs :: Address -> Limits -> DatabaseReaderT m [TxRef]
getAddressTxs Address
a Limits
limits = Address -> Limits -> DatabaseReaderT m [TxRef]
forall (m :: * -> *).
MonadUnliftIO m =>
Address -> Limits -> DatabaseReaderT 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 Word64
t = Word64 -> DatabaseReaderT m [TxData]
forall (m :: * -> *).
MonadIO m =>
Word64 -> DatabaseReaderT m [TxData]
getNumTxDataDB Word64
t
    countTxRefs :: Int -> DatabaseReaderT m ()
countTxRefs = (DatabaseStats -> Counter) -> Int -> DatabaseReaderT m ()
forall (m :: * -> *).
MonadIO m =>
(DatabaseStats -> Counter) -> Int -> ReaderT DatabaseReader m ()
incrementCounter DatabaseStats -> Counter
databaseTxRefCount
    countXPubDerivations :: Int -> DatabaseReaderT m ()
countXPubDerivations = (DatabaseStats -> Counter) -> Int -> DatabaseReaderT m ()
forall (m :: * -> *).
MonadIO m =>
(DatabaseStats -> Counter) -> Int -> ReaderT DatabaseReader m ()
incrementCounter DatabaseStats -> Counter
databaseDerivations