packages feed

haskoin-store 0.43.1 → 0.44.0

raw patch · 8 files changed

+87/−24 lines, 8 filesdep ~haskoin-store-dataPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: haskoin-store-data

API changes (from Hackage documentation)

+ Haskoin.Store: getNumTxData :: StoreReadExtra m => Word64 -> m (Maybe TxData)
+ Haskoin.Store.Common: getNumTransaction :: (Monad m, StoreReadExtra m) => Word64 -> m (Maybe Transaction)
+ Haskoin.Store.Common: getNumTxData :: StoreReadExtra m => Word64 -> m (Maybe TxData)
+ Haskoin.Store.Database.Types: TxKeyS :: (Word32, Word16) -> TxKey
+ Haskoin.Store.Database.Types: [txKeyShort] :: TxKey -> (Word32, Word16)
+ Haskoin.Store.Database.Types: decodeTxKey :: Word64 -> ((Word32, Word16), Word8)

Files

CHANGELOG.md view
@@ -4,6 +4,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html) +## 0.44.0+### Changed+- Numeric txid now 53 bits long and doesn't return transactions when hashes collide.+ ## 0.43.1 ### Fixed - Do not overcount statistics.
haskoin-store.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 983e918209925f2ad39689718c9bc45e2a911b06e1154238a04664b41899aa89+-- hash: b5a848bca1fcc3e0b0c69c2b9e0b04b81a35c40cf454e1e03fd93e3aa3679d6a  name:           haskoin-store-version:        0.43.1+version:        0.44.0 synopsis:       Storage and index for Bitcoin and Bitcoin Cash description:    Please see the README on GitHub at <https://github.com/haskoin/haskoin-store#readme> category:       Bitcoin, Finance, Network@@ -59,7 +59,7 @@     , hashable >=1.3.0.0     , haskoin-core >=0.19.0     , haskoin-node >=0.17.0-    , haskoin-store-data ==0.43.0+    , haskoin-store-data ==0.44.0     , hedis >=0.12.13     , http-types >=0.12.3     , lens >=4.18.1@@ -109,7 +109,7 @@     , haskoin-core >=0.19.0     , haskoin-node >=0.17.0     , haskoin-store-    , haskoin-store-data ==0.43.0+    , haskoin-store-data ==0.44.0     , hedis >=0.12.13     , http-types >=0.12.3     , lens >=4.18.1@@ -164,7 +164,7 @@     , haskoin-core >=0.19.0     , haskoin-node >=0.17.0     , haskoin-store-    , haskoin-store-data ==0.43.0+    , haskoin-store-data ==0.44.0     , hedis >=0.12.13     , hspec >=2.7.1     , http-types >=0.12.3
src/Haskoin/Store/BlockStore.hs view
@@ -273,6 +273,8 @@         runRocksDB . getAddressUnspents a     getAddressTxs a =         runRocksDB . getAddressTxs a+    getNumTxData =+        runRocksDB . getNumTxData  -- | Run block store process. withBlockStore ::
src/Haskoin/Store/Cache.hs view
@@ -225,6 +225,7 @@             Just cfg -> lift (runReaderT (getXPubTxs xpub limits) cfg)     getMaxGap = lift getMaxGap     getInitialGap = lift getInitialGap+    getNumTxData = lift . getNumTxData  withCache :: StoreReadBase m => Maybe CacheConfig -> CacheT m a -> m a withCache s f = runReaderT f s
src/Haskoin/Store/Common.hs view
@@ -21,6 +21,7 @@     , xPubBalsTxs     , xPubBalsUnspents     , getTransaction+    , getNumTransaction     , blockAtOrBefore     , blockAtOrAfterMTP     , deOffset@@ -40,8 +41,8 @@ import           Data.ByteString            (ByteString) import           Data.Default               (Default (..)) import           Data.Function              (on)-import           Data.Hashable              (Hashable) import qualified Data.HashSet               as H+import           Data.Hashable              (Hashable) import           Data.IntMap.Strict         (IntMap) import qualified Data.IntMap.Strict         as I import           Data.List                  (sortBy)@@ -66,7 +67,7 @@ import           Haskoin.Node               (Chain, Peer) import           Haskoin.Store.Data         (Balance (..), BlockData (..),                                              DeriveType (..), Spender,-                                             Transaction, TxData (..),+                                             Transaction (..), TxData (..),                                              TxRef (..), UnixTime, Unspent (..),                                              XPubBal (..), XPubSpec (..),                                              XPubSummary (..), XPubUnspent (..),@@ -124,6 +125,7 @@     getAddressUnspents :: Address -> Limits -> m [Unspent]     getAddressUnspents a = getAddressesUnspents [a]     getAddressesUnspents :: [Address] -> Limits -> m [Unspent]+    getNumTxData :: Word64 -> m (Maybe TxData)     xPubBals :: XPubSpec -> m [XPubBal]     xPubBals xpub = do         igap <- getInitialGap@@ -220,12 +222,12 @@ getActiveBlock :: StoreReadExtra m => BlockHash -> m (Maybe BlockData) getActiveBlock bh = getBlock bh >>= \case     Just b | blockDataMainChain b -> return (Just b)-    _ -> return Nothing+    _                             -> return Nothing  getActiveTxData :: StoreReadBase m => TxHash -> m (Maybe TxData) getActiveTxData th = getTxData th >>= \case     Just td | not (txDataDeleted td) -> return (Just td)-    _ -> return Nothing+    _                                -> return Nothing  getDefaultBalance :: StoreReadBase m => Address -> m Balance getDefaultBalance a = getBalance a >>= \case@@ -275,6 +277,13 @@ getTransaction h = runMaybeT $ do     d <- MaybeT $ getTxData h     sm <- lift $ getSpenders h+    return $ toTransaction d sm++getNumTransaction ::+    (Monad m, StoreReadExtra m) => Word64 -> m (Maybe Transaction)+getNumTransaction i = runMaybeT $ do+    d <- MaybeT $ getNumTxData i+    sm <- lift $ getSpenders (txHash (txData d))     return $ toTransaction d sm  blockAtOrBefore :: (MonadIO m, StoreReadExtra m)
src/Haskoin/Store/Database/Reader.hs view
@@ -16,20 +16,26 @@     , balanceCF     ) where -import           Conduit                      (mapC, runConduit, sinkList, (.|))+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.Word                    (Word32)+import           Data.Serialize               (encode)+import           Data.Word                    (Word32, Word64) import           Database.RocksDB             (ColumnFamily, Config (..),                                                DB (..), withDBCF, withIterCF)-import           Database.RocksDB.Query       (insert, matching, matchingSkip,+import           Database.RocksDB.Query       (insert, matching,+                                               matchingAsListCF, matchingSkip,                                                retrieve, retrieveCF) import           Haskoin                      (Address, BlockHash, BlockHeight,-                                               Network, OutPoint (..), TxHash)+                                               Network, OutPoint (..), TxHash,+                                               txHash) import           Haskoin.Store.Common import           Haskoin.Store.Data import           Haskoin.Store.Database.Types@@ -139,6 +145,19 @@ getTxDataDB th DatabaseReader{databaseHandle = db} =     retrieveCF db (txCF db) (TxKey th) +getNumTxDataDB :: MonadIO m => Word64 -> DatabaseReader -> m (Maybe TxData)+getNumTxDataDB i r@DatabaseReader{databaseHandle = db} = do+    let (sk, w) = decodeTxKey i+    ls <- liftIO $ matchingAsListCF db (txCF db) (TxKeyS sk)+    let f t = let bs = encode $ txHash (txData t)+                  b = BS.head (BS.drop 6 bs)+                  w' = b .&. 0xf8+              in w == w'+        xs = filter f $ map snd ls+    case xs of+        [x] -> return $ Just x+        _   -> return Nothing+ getSpenderDB :: MonadIO m => OutPoint -> DatabaseReader -> m (Maybe Spender) getSpenderDB op DatabaseReader{databaseHandle = db} =     retrieveCF db (spenderCF db) $ SpenderKey op@@ -176,7 +195,7 @@         case start limits of             Nothing -> matching it (AddrTxKeyA a)             Just (AtTx txh) ->-                getTxDataDB txh bdb >>= \case+                lift (getTxDataDB txh bdb) >>= \case                     Just TxData {txDataBlock = b@BlockRef {}} ->                         matchingSkip it (AddrTxKeyA a) (AddrTxKeyB a b)                     _ -> matching it (AddrTxKeyA a)@@ -216,14 +235,15 @@     x it .| applyLimitsC limits .| mapC (uncurry toUnspent) .| sinkList   where     x it = case start limits of-        Nothing -> matching it (AddrOutKeyA a)+        Nothing ->+            matching it (AddrOutKeyA a)         Just (AtBlock h) ->             matchingSkip                 it                 (AddrOutKeyA a)                 (AddrOutKeyB a (BlockRef h maxBound))         Just (AtTx txh) ->-            getTxDataDB txh bdb >>= \case+            lift (getTxDataDB txh bdb) >>= \case                 Just TxData {txDataBlock = b@BlockRef {}} ->                     matchingSkip it (AddrOutKeyA a) (AddrOutKeyB a b)                 _ -> matching it (AddrOutKeyA a)@@ -246,3 +266,4 @@     getAddressTxs a limits = ask >>= getAddressTxsDB a limits     getMaxGap = asks databaseMaxGap     getInitialGap = asks databaseInitialGap+    getNumTxData t = ask >>= getNumTxDataDB t
src/Haskoin/Store/Database/Types.hs view
@@ -12,6 +12,7 @@     , MemKey(..)     , SpenderKey(..)     , TxKey(..)+    , decodeTxKey     , UnspentKey(..)     , VersionKey(..)     , BalVal(..)@@ -26,7 +27,8 @@  import           Control.DeepSeq        (NFData) import           Control.Monad          (guard)-import           Data.Bits              (Bits, shiftL, shiftR, (.|.))+import           Data.Bits              (Bits, shift, shiftL, shiftR, (.&.),+                                         (.|.)) import           Data.ByteString        (ByteString) import qualified Data.ByteString        as BS import           Data.ByteString.Short  (ShortByteString)@@ -35,7 +37,9 @@ import           Data.Either            (fromRight) import           Data.Hashable          (Hashable) import           Data.Serialize         (Serialize (..), decode, encode,-                                         getBytes, getWord8, putWord8, runPut)+                                         getBytes, getWord16be, getWord32be,+                                         getWord8, putWord32be, putWord64be,+                                         putWord8, runGet, runPut) import           Data.Word              (Word16, Word32, Word64, Word8) import           Database.RocksDB.Query (Key, KeyValue) import           GHC.Generics           (Generic)@@ -137,6 +141,7 @@  -- | Transaction database key. data TxKey = TxKey { txKey :: TxHash }+           | TxKeyS { txKeyShort :: (Word32, Word16) }     deriving (Show, Read, Eq, Ord, Generic, Hashable)  instance Serialize TxKey where@@ -144,9 +149,25 @@     put (TxKey h) = do         putWord8 0x02         put h+    put (TxKeyS h) = do+        putWord8 0x02+        put h     get = do         guard . (== 0x02) =<< getWord8         TxKey <$> get++decodeTxKey :: Word64 -> ((Word32, Word16), Word8)+decodeTxKey i =+    let masked = i .&. 0x001fffffffffffff+        wb = masked `shift` 11+        bs = runPut (putWord64be wb)+        g = do+            w1 <- getWord32be+            w2 <- getWord16be+            w3 <- getWord8+            return (w1, w2, w3)+        Right (w1, w2, w3) = runGet g bs+    in ((w1, w2), w3)  instance Key TxKey instance KeyValue TxKey TxData
src/Haskoin/Store/Web.hs view
@@ -316,6 +316,7 @@     xPubSummary = runInWebReader . xPubSummary     xPubUnspents xpub = runInWebReader . xPubUnspents xpub     xPubTxs xpub = runInWebReader . xPubTxs xpub+    getNumTxData = runInWebReader . getNumTxData  instance (MonadUnliftIO m, MonadLoggerIO m) => StoreReadBase (WebT m) where     getNetwork = lift getNetwork@@ -338,6 +339,7 @@     xPubTxs xpub = lift . xPubTxs xpub     getMaxGap = lift getMaxGap     getInitialGap = lift getInitialGap+    getNumTxData = lift . getNumTxData  ------------------- -- Path Handlers --@@ -1518,7 +1520,7 @@ scottyBinfoTx =     lift (asks (webNumTxId . webConfig)) >>= \numtxid ->     S.param "txid" >>= \txid ->-    withMetrics rawtxResponseTime 1 $ go numtxid (decodeBinfoTxId txid)+    withMetrics rawtxResponseTime 1 $ go numtxid txid   where     get_format = S.param "format" `S.rescue` const (return ("json" :: Text))     js numtxid t = do@@ -1528,11 +1530,14 @@     hex t = do         setHeaders         S.text . TL.fromStrict . encodeHex . encode $ transactionData t-    go numtxid h = getTransaction h >>= \case-        Nothing -> raise rawtxErrors ThingNotFound-        Just t -> get_format >>= \case-            "hex" -> hex t-            _     -> js numtxid t+    go numtxid txid =+        let f (BinfoTxIdHash h)  = getTransaction h+            f (BinfoTxIdIndex i) = getNumTransaction i+        in f txid >>= \case+            Nothing -> raise rawtxErrors ThingNotFound+            Just t -> get_format >>= \case+                "hex" -> hex t+                _     -> js numtxid t  -- GET Network Information --